├── .gitignore
├── Conteúdo A - Aprendendo Python
├── prog01-aprendendo-pythonV2.ipynb
└── prog01_AprendendoPython.ipynb
├── Conteúdo B - Aprendendo Numpy
├── prog02-aprendendo-numpyV2.ipynb
└── prog02_AprendendoNumpy.ipynb
├── Conteúdo C - Aprendendo Matplotlib
├── prog03-aprendendo-matplotlibV2.ipynb
└── prog03_AprendendoMatplotlib.ipynb
├── Conteúdo D - Operações Matriciais
├── .ipynb_checkpoints
│ └── prog04_OperacoesMatriciais-checkpoint.ipynb
├── prog04-operacoes-matriciaisV2.ipynb
└── prog04_OperacoesMatriciais.ipynb
├── Conteúdo E - Aplicação de Matrizes
├── .ipynb_checkpoints
│ ├── prog05-aplicacoes-matrizesV2-checkpoint.ipynb
│ └── prog05_AplicacaoDeMatrizes-checkpoint.ipynb
├── prog05-aplicacoes-matrizesV2.ipynb
└── prog05_AplicacaoDeMatrizes.ipynb
├── Conteúdo F - Matriz Transposta
└── prog06_MatrizTransposta.ipynb
├── Conteúdo G - Matriz Inversa
└── prog07_MatrizInversa.ipynb
├── Conteúdo H - Determinante
└── prog08_Determinante.ipynb
├── Conteúdo I - Sistemas Lineares
└── prog09_SistemasLineares.ipynb
├── Conteúdo J - Transformações Lineares
├── .ipynb_checkpoints
│ └── prog10_TransformacoesLineares-checkpoint.ipynb
├── plot_helper.py
└── prog10_TransformacoesLineares.ipynb
├── Conteúdo K - Estudo de Sistemas de Equações
├── plot_helper.py
└── prog11_EstudoSistemasDeEquacoes.ipynb
├── Conteúdo L - Autovalores e Autovetores
└── prog12_AutovaloresAutovetores.ipynb
├── Conteúdo M - Autovalores em Ecologia
└── prog13_AutovaloresEmEcologia.ipynb
├── Conteúdo N - Transformando um Círculo em uma Elípse
├── plot_helper.py
└── prog14_TransCircElip.ipynb
├── Conteúdo O - A Geometria das Transformações Lineares
└── prog15_AGeometriaDasTransformacoesLineares.ipynb
├── Conteúdo P - Construção de Curvas por Pontos Especificados
└── prog16_ConstrucaoDeCurvasPorPontosEspecificados.ipynb
├── Conteúdo Q - Criptografia
├── .ipynb_checkpoints
│ └── prog17_Criptografia-checkpoint.ipynb
└── prog17_Criptografia.ipynb
├── Conteúdo R - Teoria dos Grafos
└── prog18_TeoriaDosGrafos.ipynb
├── Conteúdo S - Cadeias de Markov
└── prog19_CadeiasDeMarkov.ipynb
├── Conteúdo T - Google Page Rank
└── prog20_GooglePageRank.ipynb
├── Conteúdo U - Problemas de Mínimos Quadráticos
└── prog21_MinimosQuadraticos.ipynb
├── Conteúdo V - Processamento de Imagens Digitais
├── melhorramodomundo.jpg
└── prog22_ProcessamentoDeImagensDigitais.ipynb
├── Conteúdo W - Verifique a Instalação
└── VerifiqueInstalacao.ipynb
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | Conteúdo B - Aprendendo Numpy/.ipynb_checkpoints/prog02-aprendendo-numpyV2-checkpoint.ipynb
3 | Conteúdo A - Aprendendo Python/.ipynb_checkpoints/prog01_AprendendoPython-checkpoint.ipynb
4 | Conteúdo A - Aprendendo Python/.ipynb_checkpoints/prog01-aprendendo-pythonV2-checkpoint.ipynb
5 | Conteúdo A - Aprendendo Python/.ipynb_checkpoints/prog01_AprendendoPython-checkpoint.ipynb
6 | Conteúdo C - Aprendendo Matplotlib/.ipynb_checkpoints/prog03-aprendendo-matplotlibV2-checkpoint.ipynb
7 | Conteúdo D - Operações Matriciais/.ipynb_checkpoints/prog04-operacoes-matriciaisV2-checkpoint.ipynb
8 |
--------------------------------------------------------------------------------
/Conteúdo D - Operações Matriciais/prog04-operacoes-matriciaisV2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "kernelspec": {
6 | "display_name": "Python 3",
7 | "language": "python",
8 | "name": "python3"
9 | },
10 | "language_info": {
11 | "codemirror_mode": {
12 | "name": "ipython",
13 | "version": 3
14 | },
15 | "file_extension": ".py",
16 | "mimetype": "text/x-python",
17 | "name": "python",
18 | "nbconvert_exporter": "python",
19 | "pygments_lexer": "ipython3",
20 | "version": "3.8.7"
21 | },
22 | "colab": {
23 | "name": "prog04-operacoes-matriciaisV2.ipynb",
24 | "provenance": [],
25 | "include_colab_link": true
26 | }
27 | },
28 | "cells": [
29 | {
30 | "cell_type": "markdown",
31 | "metadata": {
32 | "id": "view-in-github",
33 | "colab_type": "text"
34 | },
35 | "source": [
36 | ""
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {
42 | "id": "WekvbqhFUxQJ"
43 | },
44 | "source": [
45 | "# Operações Matriciais\n",
46 | "#### Vamos ver como matrizes podem ser combinadas através das operações aritméticas de adição, subtração e multiplicação."
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {
52 | "id": "PGpuggAYUxQS"
53 | },
54 | "source": [
55 | "### Soma"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {
61 | "id": "v5Zr1ykoUxQT"
62 | },
63 | "source": [
64 | "$$\\begin{bmatrix}\n",
65 | " a_{11} & a_{12} & ... & a_{1n} \\\\\n",
66 | " a_{21} & a_{22} & ... & a_{2n} \\\\\n",
67 | " : & : & ... & : \\\\\n",
68 | " a_{m1} & a_{m2} & ... & a_{mn} \\\\\n",
69 | " \\end{bmatrix}_{m_{x}n} + \n",
70 | " \\begin{bmatrix}\n",
71 | " b_{11} & b_{12} & ... & b_{1n} \\\\\n",
72 | " b_{21} & b_{22} & ... & b_{2n} \\\\\n",
73 | " : & : & ... & : \\\\\n",
74 | " b_{m1} & b_{m2} & ... & b_{mn} \\\\\n",
75 | " \\end{bmatrix}_{m_{x}n} = \n",
76 | " \\begin{bmatrix}\n",
77 | " a_{11} + b_{11} & a_{12} + b_{12} & ... & a_{1n} + b_{1n} \\\\\n",
78 | " a_{21} + b_{21} & a_{22} + b_{22} & ... & a_{2n} + b_{2n} \\\\\n",
79 | " : & : & ... & : \\\\\n",
80 | " a_{m1} + b_{m1} & a_{m2} + b_{m2} & ... & a_{mn} + b_{mn} \\\\\n",
81 | " \\end{bmatrix}_{m_{x}n}$$"
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {
87 | "id": "ICGlNKxmUxQU"
88 | },
89 | "source": [
90 | "### Subtração"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "metadata": {
96 | "id": "G-C7_WRVUxQV"
97 | },
98 | "source": [
99 | "$$\\begin{bmatrix}\n",
100 | " a_{11} & a_{12} & ... & a_{1n} \\\\\n",
101 | " a_{21} & a_{22} & ... & a_{2n} \\\\\n",
102 | " : & : & ... & : \\\\\n",
103 | " a_{m1} & a_{m2} & ... & a_{mn} \\\\\n",
104 | " \\end{bmatrix}_{m_{x}n} - \n",
105 | " \\begin{bmatrix}\n",
106 | " b_{11} & b_{12} & ... & b_{1n} \\\\\n",
107 | " b_{21} & b_{22} & ... & b_{2n} \\\\\n",
108 | " : & : & ... & : \\\\\n",
109 | " b_{m1} & b_{m2} & ... & b_{mn} \\\\\n",
110 | " \\end{bmatrix}_{m_{x}n} = \n",
111 | " \\begin{bmatrix}\n",
112 | " a_{11} - b_{11} & a_{12} - b_{12} & ... & a_{1n} - b_{1n} \\\\\n",
113 | " a_{21} - b_{21} & a_{22} - b_{22} & ... & a_{2n} - b_{2n} \\\\\n",
114 | " : & : & ... & : \\\\\n",
115 | " a_{m1} - b_{m1} & a_{m2} - b_{m2} & ... & a_{mn} - b_{mn} \\\\\n",
116 | " \\end{bmatrix}_{m_{x}n}$$"
117 | ]
118 | },
119 | {
120 | "cell_type": "markdown",
121 | "metadata": {
122 | "id": "rV8zDHj2UxQW"
123 | },
124 | "source": [
125 | "### Multiplicação"
126 | ]
127 | },
128 | {
129 | "cell_type": "markdown",
130 | "metadata": {
131 | "id": "tOEtDQaaUxQW"
132 | },
133 | "source": [
134 | "$$A_{m_{x}n}.B_{n_{x}p} = C_{m_{x}p}$$"
135 | ]
136 | },
137 | {
138 | "cell_type": "markdown",
139 | "metadata": {
140 | "id": "Pqbg2kFdUxQX"
141 | },
142 | "source": [
143 | "### Multiplicação de uma Matriz por um Escalar"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {
149 | "id": "3pvrMfPuUxQX"
150 | },
151 | "source": [
152 | "$$x_{escalar}.\\begin{bmatrix}\n",
153 | " a_{11} & a_{12} & ... & a_{1n} \\\\\n",
154 | " a_{21} & a_{22} & ... & a_{2n} \\\\\n",
155 | " : & : & ... & : \\\\\n",
156 | " a_{m1} & a_{m2} & ... & a_{mn} \\\\\n",
157 | " \\end{bmatrix}_{m_{x}n} = \n",
158 | " \\begin{bmatrix}\n",
159 | " x.a_{11} & x.a_{12} & ... & x.a_{1n} \\\\\n",
160 | " x.a_{21} & x.a_{22} & ... & x.a_{2n} \\\\\n",
161 | " : & : & ... & : \\\\\n",
162 | " x.a_{m1} & x.a_{m2} & ... & x.a_{mn} \\\\\n",
163 | " \\end{bmatrix}_{m_{x}n}$$"
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {
169 | "id": "1xc9zWAKUxQY"
170 | },
171 | "source": [
172 | "Experimente uma função que realiza essas operações:"
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "metadata": {
178 | "id": "8Sw43DwxUxQZ"
179 | },
180 | "source": [
181 | "# importando a biblioteca numpy do Python \n",
182 | "import numpy as np "
183 | ],
184 | "execution_count": 1,
185 | "outputs": []
186 | },
187 | {
188 | "cell_type": "code",
189 | "metadata": {
190 | "id": "hgsU1ZIgUxQZ"
191 | },
192 | "source": [
193 | "# criando a função principal\n",
194 | "def main():\n",
195 | " \n",
196 | " # menu de escolhas do progama em um loop com uma ordem de parada\n",
197 | " while True: \n",
198 | " \n",
199 | " print(\"\\nEscolha uma das opções de operações com matrizes abaixo:\")\n",
200 | " print(\" 1 - Soma entre duas matrizes.\")\n",
201 | " print(\" 2 - Subtração entre duas matrizes.\")\n",
202 | " print(\" 3 - Multiplicação entre duas matrizes.\")\n",
203 | " print(\" 4 - Multiplicação de uma matriz por um escalar.\")\n",
204 | " print(\" 5 - Sair do progama\")\n",
205 | " \n",
206 | " # loop com ordem de parada para que o progama aceite a entrada correta\n",
207 | " while True:\n",
208 | " \n",
209 | " opcao = int(input(\"Insira uma opção abaixo: \"))\n",
210 | " \n",
211 | " if opcao >= 1 and opcao <= 5:\n",
212 | " break\n",
213 | " # parar a execução do loop caso o usuário queira terminar o progama\n",
214 | " elif(opcao == 5): \n",
215 | " break\n",
216 | " else:\n",
217 | " print(\"Entrada errada. Digite novamente.\\n\")\n",
218 | " \n",
219 | " # parada geral do progama\n",
220 | " if(opcao == 5):\n",
221 | " break\n",
222 | " \n",
223 | " # indo para próximas linhas\n",
224 | " print(\"\\n\")\n",
225 | " \n",
226 | " # recendo a quantidade de linhas e colunas das matrizes\n",
227 | " linhaA = int(input(\"Informe a quantidade de linhas da matriz A: \"))\n",
228 | " colunaA = int(input(\"Informe a quantidade de colunas da matriz A: \"))\n",
229 | " linhaB = int(input(\"Informe a quantidade de linhas da matriz B: \"))\n",
230 | " colunaB = int(input(\"Informe a quantidade de colunas da matriz B: \"))\n",
231 | " \n",
232 | " # inicializando as matrizes com suas devidas ordens e com lixo de memória\n",
233 | " A = np.empty([linhaA, colunaA], dtype = float) \n",
234 | " B = np.empty([linhaB, colunaB], dtype = float)\n",
235 | " \n",
236 | " # indo para próxima linha\n",
237 | " print(\"\\n\")\n",
238 | " \n",
239 | " # estrutura de repetição for para implementar os elementos da matriz A\n",
240 | " for i in range(0, linhaA):\n",
241 | " for j in range(0, colunaA):\n",
242 | " A[i][j] = float(input(\"Digite o elemento [{}][{}] da matriz A: \".format(i + 1,j + 1)))\n",
243 | " \n",
244 | " # indo para próxima linha\n",
245 | " print(\"\\n\")\n",
246 | " \n",
247 | " # estrutura de repetição for para implementar os elementos da matriz B\n",
248 | " for i in range(0, linhaB):\n",
249 | " for j in range(0, colunaB):\n",
250 | " B[i][j] = float(input(\"Digite o elemento [{}][{}] da matriz B: \".format(i + 1, j + 1)))\n",
251 | " \n",
252 | " # indo para próxima linha\n",
253 | " print(\"\\n\")\n",
254 | " \n",
255 | " # imprime a matriz A\n",
256 | " print(\"A matriz A é: \\n{}\".format(A))\n",
257 | " \n",
258 | " # indo para próxima linha\n",
259 | " print(\"\\n\")\n",
260 | " \n",
261 | " # imprime a matriz B\n",
262 | " print(\"A matriz B é: \\n{}\".format(B))\n",
263 | " \n",
264 | " # recebe um escalar para ser usado na função da opção 4\n",
265 | " if(opcao == 4):\n",
266 | " escalar = float(input(\"\\nInforme um escalar: \"))\n",
267 | " \n",
268 | " # indo para próxima linha\n",
269 | " print(\"\\n\")\n",
270 | " \n",
271 | " # caso o usário escolha a opção 1, relativa a soma\n",
272 | " if(opcao == 1):\n",
273 | " print(\"\\nSoma:\\n\\n {}\".format(soma(A, linhaA, colunaA, B, linhaB, colunaB)))\n",
274 | " # se não se, o usuário escolher a opção 2, realtivo a subtração\n",
275 | " elif(opcao == 2):\n",
276 | " print(\"\\nSubtração: \\n\\n{}\".format(subtracao(A, linhaA, colunaA, B, linhaB, colunaB)))\n",
277 | " # se não se, o usuário escolher a opção 3, realtivo a multiplicação\n",
278 | " elif(opcao == 3):\n",
279 | " print(\"\\nMultiplicação: \\n\\n{}\".format(multiplicacao(A, linhaA, colunaA, B, linhaB, colunaB)))\n",
280 | " # se não se, o usuário escolher a opção 4, realtivo a multiplicação de um escalar com uma matriz\n",
281 | " elif(opcao == 4):\n",
282 | " print(\"\\nMultiplicação de um escalar com uma matriz: \\n\\n{}\".format(multiplicaEscalar(A, B, escalar)))\n",
283 | " \n",
284 | " return 0"
285 | ],
286 | "execution_count": 2,
287 | "outputs": []
288 | },
289 | {
290 | "cell_type": "code",
291 | "metadata": {
292 | "id": "jnEAinF_UxQc"
293 | },
294 | "source": [
295 | "# função que realiza a soma entre duas matrizes\n",
296 | "def soma(matrizA, linhaA, colunaA, matrizB, linhaB, colunaB):\n",
297 | " \n",
298 | " # verificando se a operação está definida\n",
299 | " if(linhaA != linhaB or colunaA != colunaB):\n",
300 | " # retornando a mensagem de erro caso não seja uma operação compatível\n",
301 | " return \"operação com tais matrizes incompatíveis. Tente novamente.\"\n",
302 | " \n",
303 | " # definindo a soma\n",
304 | " somando = matrizA + matrizB\n",
305 | " \n",
306 | " # retornando o resultado da função\n",
307 | " return somando"
308 | ],
309 | "execution_count": 3,
310 | "outputs": []
311 | },
312 | {
313 | "cell_type": "code",
314 | "metadata": {
315 | "id": "D9PB1YSRUxQc"
316 | },
317 | "source": [
318 | "# função que realiza a subtração de duas matrizes\n",
319 | "def subtracao(matrizA, linhaA, colunaA, matrizB, linhaB, colunaB):\n",
320 | " \n",
321 | " # verificando se a operação está definida\n",
322 | " if(linhaA != linhaB or colunaA != colunaB):\n",
323 | " # retornando uma mensagem de erro caso a operação não seja compatível\n",
324 | " return \"operação com tais matrizes incompatíveis. Tente novamente.\"\n",
325 | " \n",
326 | " #escolhendo a subtração\n",
327 | " print(\"1) A - B = ??\")\n",
328 | " print(\"2) B - A = ??\")\n",
329 | " \n",
330 | " # recebendo a opção informada acima e verificando se foi digitado corretamente\n",
331 | " while True:\n",
332 | " opcao = int(input(\"Informe sua opção: \"))\n",
333 | " if(opcao == 1 or opcao == 2):\n",
334 | " break\n",
335 | " else:\n",
336 | " print(\"Opção inválida, digite novamente.\\n\")\n",
337 | " \n",
338 | " #realizando a operação\n",
339 | " if(opcao == 1):\n",
340 | " # definindo a operação de subtração\n",
341 | " subtraindo = matrizA - matrizB\n",
342 | " # retornando o resultado da função\n",
343 | " return subtraindo\n",
344 | " elif(opcao == 2):\n",
345 | " # definindo a operação de subtração\n",
346 | " subtraindo = matrizB - matrizA\n",
347 | " # retornando o resultado da função\n",
348 | " return subtraindo"
349 | ],
350 | "execution_count": 4,
351 | "outputs": []
352 | },
353 | {
354 | "cell_type": "code",
355 | "metadata": {
356 | "id": "Mi8nDHhxUxQd"
357 | },
358 | "source": [
359 | "# função que realiza a multiplicação de duas matrizes\n",
360 | "def multiplicacao(matrizA, linhaA, colunaA, matrizB, linhaB, colunaB):\n",
361 | " \n",
362 | " #escolhendo a multiplicação\n",
363 | " print(\"1) A x B = ??\")\n",
364 | " print(\"2) B x A = ??\")\n",
365 | " \n",
366 | " # recebendo a opção informada acima e fazendo uma verificação de segurança\n",
367 | " while True:\n",
368 | " opcao = int(input(\"Informe sua opção: \"))\n",
369 | " if(opcao == 1 or opcao == 2):\n",
370 | " break\n",
371 | " else:\n",
372 | " print(\"Opção inválida, digite novamente.\\n\")\n",
373 | " \n",
374 | " # verificando se a operação está definida\n",
375 | " if(opcao == 1):\n",
376 | " if(colunaA != linhaB):\n",
377 | " # retorna uma mensagem de erro caso a operação não seja compatível\n",
378 | " return \"operação com tais matrizes incompatíveis. Tente novamente.\"\n",
379 | " elif(opcao == 2):\n",
380 | " if(colunaB != linhaA):\n",
381 | " # retorna uma mensagem de erro caso a operação não seja compatível\n",
382 | " return \"operação com tais matrizes incompatíveis. Tente novamente.\"\n",
383 | " \n",
384 | " #realizando a operação\n",
385 | " if(opcao == 1):\n",
386 | " # definindo a operação de multiplicação\n",
387 | " multiplicando = np.dot(matrizA, matrizB)\n",
388 | " # retornando o resultado da função\n",
389 | " return multiplicando\n",
390 | " elif(opcao == 2):\n",
391 | " # definindo a operação de multiplicação\n",
392 | " multiplicando = np.dot(matrizB,matrizA)\n",
393 | " # retornando o resultado da função\n",
394 | " return multiplicando"
395 | ],
396 | "execution_count": 5,
397 | "outputs": []
398 | },
399 | {
400 | "cell_type": "code",
401 | "metadata": {
402 | "id": "Rt0a47DzUxQe"
403 | },
404 | "source": [
405 | "# função que multiplica um escalar pela matriz\n",
406 | "def multiplicaEscalar(matrizA, matrizB, escalar):\n",
407 | " \n",
408 | " # escolhendo a matriz\n",
409 | " print(\"Qual matriz você quer multiplicar pelo escalar?\")\n",
410 | " print(\"1) matriz A\")\n",
411 | " print(\"2) matriz B\")\n",
412 | " \n",
413 | " # recebendo a opção informada acima e fazendo uma verificação de segurança\n",
414 | " while True:\n",
415 | " opcao = int(input(\"Informe sua opção: \"))\n",
416 | " if(opcao == 1 or opcao == 2):\n",
417 | " break\n",
418 | " else:\n",
419 | " print(\"Opção inválida, digite novamente.\\n\")\n",
420 | " \n",
421 | " if(opcao == 1):\n",
422 | " # definindo a multiplicação da matrizA por um escalar\n",
423 | " novaMatriz = escalar * matrizA\n",
424 | " # retornando o resultado da função\n",
425 | " return novaMatriz\n",
426 | " elif(opcao == 2):\n",
427 | " # definindo a multiplicação da matrizB por um escalar\n",
428 | " novaMatriz = escalar * matrizB\n",
429 | " # retornando o resultado da função\n",
430 | " return novaMatriz"
431 | ],
432 | "execution_count": 6,
433 | "outputs": []
434 | },
435 | {
436 | "cell_type": "code",
437 | "metadata": {
438 | "id": "RVZ8i82fUxQf"
439 | },
440 | "source": [
441 | "if __name__ == '__main__':\n",
442 | " main() # chamada da função main"
443 | ],
444 | "execution_count": 7,
445 | "outputs": []
446 | },
447 | {
448 | "cell_type": "markdown",
449 | "metadata": {
450 | "id": "6LMyPw1jUxQg"
451 | },
452 | "source": [
453 | "### Alguma Dúvida? Entre em Contato Comigo: [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br)"
454 | ]
455 | }
456 | ]
457 | }
--------------------------------------------------------------------------------
/Conteúdo F - Matriz Transposta/prog06_MatrizTransposta.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Matriz Transposta\n",
8 | "#### A transposta de uma matriz MA é uma matriz que possui os mesmos elementos de MA, mas postos em posições diferentes. Pode-se obter transportando ordenadamente os elementos das linhas de MA para as colunas de MA transposta."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "Desse modo, tendo uma matriz $MA = (ma_{ij})_{m_{x}n}$ a transposta de MA é $MA^{t} = (ma^{'}_{ji})_{n_{x}m}$."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "$MA = \\begin{bmatrix}\n",
23 | " a_{1,1} & a_{1,2} & ... & a_{1,n} \\\\\n",
24 | " a_{2,1} & a_{2,2} & ... & a_{2,n} \\\\\n",
25 | " : & : & : & : \\\\\n",
26 | " a_{m,1} & a_{m,2} & ... & a_{m,n} \\\\\n",
27 | " \\end{bmatrix}\n",
28 | "MA^{t} = \\begin{bmatrix}\n",
29 | " a_{1,1} & a_{2,1} & : & a_{m,1} \\\\\n",
30 | " a_{1,2} & a_{2,2} & : & a_{m,2} \\\\\n",
31 | " ... & ... & : & ... \\\\\n",
32 | " a_{1,n} & a_{2,n} & : & a_{m,n} \\\\\n",
33 | " \\end{bmatrix}$"
34 | ]
35 | },
36 | {
37 | "cell_type": "code",
38 | "execution_count": 1,
39 | "metadata": {},
40 | "outputs": [],
41 | "source": [
42 | "import numpy as np # importando a biblioteca numpy padrão do Python"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 2,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "# criando a função de matriz transposta\n",
52 | "def transposta():\n",
53 | " \n",
54 | " # recebe a quantidade de linhas da matriz\n",
55 | " linha = int(input(\"Informe quantas linhas tem sua matriz: \")) \n",
56 | " # recebe a quantidade de colunas da matriz\n",
57 | " coluna = int(input(\"Informe quantas colunas tem sua matriz: \")) \n",
58 | " \n",
59 | " # comandos de ir para a próxima linha\n",
60 | " print(\"\\n\") \n",
61 | " \n",
62 | " # iniciando uma matriz de números reais com linhas e colunas definidas\n",
63 | " A = np.empty([linha,coluna], dtype = float)\n",
64 | "\n",
65 | " # estrutura for aninhada que recebe os elementos da matriz\n",
66 | " for i in range(0, linha):\n",
67 | " for j in range(0, coluna):\n",
68 | " A[i][j] = float(input(\"Insira o elemento [{}][{}] da matriz: \".format(i + 1,j + 1)))\n",
69 | "\n",
70 | " #imprime na tela a matriz original\n",
71 | " print(\"\\n\\nA matriz digitada é:\\n\\n{}\\n\\n\".format(A))\n",
72 | "\n",
73 | " # definindo a matriz transposta com uma função do numpy\n",
74 | " A_T = np.transpose(A) \n",
75 | "\n",
76 | " # imprime na tela a matriz transposta\n",
77 | " print(\"A matriz transposta é:\\n\\n{}\\n\\n\". format(A_T))\n",
78 | "\n",
79 | " # definindo a matriz transposta da matriz A_T, voltando a ser a matriz A\n",
80 | " A = np.transpose(A_T)\n",
81 | "\n",
82 | " # imprime na tela a matriz tranposta da mesma já transposta, ou seja, retornará a matriz original\n",
83 | " print(\"A matriz transposta da transpostada é:\\n\\n{}\".format(A))\n",
84 | " \n",
85 | " # função não retorna nenhum valor\n",
86 | " return None"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": 3,
92 | "metadata": {},
93 | "outputs": [
94 | {
95 | "name": "stdin",
96 | "output_type": "stream",
97 | "text": [
98 | "Informe quantas linhas tem sua matriz: 2\n",
99 | "Informe quantas colunas tem sua matriz: 3\n"
100 | ]
101 | },
102 | {
103 | "name": "stdout",
104 | "output_type": "stream",
105 | "text": [
106 | "\n",
107 | "\n"
108 | ]
109 | },
110 | {
111 | "name": "stdin",
112 | "output_type": "stream",
113 | "text": [
114 | "Insira o elemento [1][1] da matriz: 1\n",
115 | "Insira o elemento [1][2] da matriz: 2\n",
116 | "Insira o elemento [1][3] da matriz: 3\n",
117 | "Insira o elemento [2][1] da matriz: 4\n",
118 | "Insira o elemento [2][2] da matriz: 5\n",
119 | "Insira o elemento [2][3] da matriz: 6\n"
120 | ]
121 | },
122 | {
123 | "name": "stdout",
124 | "output_type": "stream",
125 | "text": [
126 | "\n",
127 | "\n",
128 | "A matriz digitada é:\n",
129 | "\n",
130 | "[[1. 2. 3.]\n",
131 | " [4. 5. 6.]]\n",
132 | "\n",
133 | "\n",
134 | "A matriz transposta é:\n",
135 | "\n",
136 | "[[1. 4.]\n",
137 | " [2. 5.]\n",
138 | " [3. 6.]]\n",
139 | "\n",
140 | "\n",
141 | "A matriz transposta da transpostada é:\n",
142 | "\n",
143 | "[[1. 2. 3.]\n",
144 | " [4. 5. 6.]]\n"
145 | ]
146 | }
147 | ],
148 | "source": [
149 | "# imprimindo a função criada\n",
150 | "transposta()"
151 | ]
152 | },
153 | {
154 | "cell_type": "markdown",
155 | "metadata": {},
156 | "source": [
157 | "### Alguma Dúvida? Entre em Contato Comigo:"
158 | ]
159 | },
160 | {
161 | "cell_type": "markdown",
162 | "metadata": {},
163 | "source": [
164 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);"
165 | ]
166 | }
167 | ],
168 | "metadata": {
169 | "kernelspec": {
170 | "display_name": "Python 3",
171 | "language": "python",
172 | "name": "python3"
173 | },
174 | "language_info": {
175 | "codemirror_mode": {
176 | "name": "ipython",
177 | "version": 3
178 | },
179 | "file_extension": ".py",
180 | "mimetype": "text/x-python",
181 | "name": "python",
182 | "nbconvert_exporter": "python",
183 | "pygments_lexer": "ipython3",
184 | "version": "3.7.4"
185 | }
186 | },
187 | "nbformat": 4,
188 | "nbformat_minor": 4
189 | }
190 |
--------------------------------------------------------------------------------
/Conteúdo G - Matriz Inversa/prog07_MatrizInversa.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Matriz Inversa\n",
8 | "#### A matriz inversa ou matriz invertível é um tipo de matriz quadrada, ou seja, que possui o mesmo número de linhas (m) e colunas (n). Ela ocorre quando o produto de duas matrizes resulta numa matriz identidade de mesma ordem (mesmo número de linhas e colunas)."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "##### Referência: Álgebra Linear com aplicações / Anton Howard e Chris Rorres; trad. Claus Ivo Doering. - 8. ed. - Porto Alegre: Bookman, 2001."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "### Definição"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "Dada uma matriz quadrada **A**, se pudermos encontrar uma matriz **B** de mesmo tamanho tal que **AB = BA = I**, então diremos que **A** é **invertível** e que **B** é uma **inversa** de **A**. Se não puder ser encontrada uma tal matriz **B** então diremos que **A** é **não-invertível** ou **singular**."
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "A matriz"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "$$A = \\begin{bmatrix}\n",
44 | " a & b \\\\\n",
45 | " c & d \\\\\n",
46 | " \\end{bmatrix}$$"
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {},
52 | "source": [
53 | "é invertível se **ad - bc ≠ 0** ou **det(A) ≠ 0**, caso em que a inversa é dada pela fórmula"
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "$A^{-1} = \\frac{1}{ad-bc}\\begin{bmatrix}\n",
61 | " d & -b \\\\\n",
62 | " -c & a \\\\\n",
63 | " \\end{bmatrix} = \\begin{bmatrix}\n",
64 | " \\frac{d}{ad-bc} & \\frac{-b}{ad-bc} \\\\\n",
65 | " \\frac{-c}{ad-bc} & \\frac{a}{ad-bc} \\\\\n",
66 | " \\end{bmatrix}$"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "### Exemplo: Encontrando Matrizes Inversas com Python"
74 | ]
75 | },
76 | {
77 | "cell_type": "markdown",
78 | "metadata": {},
79 | "source": [
80 | "Vamos agora ver como tal processo é fácil computacionalmente:"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": 1,
86 | "metadata": {},
87 | "outputs": [],
88 | "source": [
89 | "# importando a biblioteca de funções numpy\n",
90 | "import numpy as np "
91 | ]
92 | },
93 | {
94 | "cell_type": "code",
95 | "execution_count": 2,
96 | "metadata": {},
97 | "outputs": [],
98 | "source": [
99 | "# função que calcula a matriz inversa\n",
100 | "def inversa():\n",
101 | "\n",
102 | " print(\"Progama que calcula a matriz inversa\")\n",
103 | "\n",
104 | " # variáveis que recebem a quantidade de linhas e colunas da matriz\n",
105 | " linha = int(input(\"Informe a quantidade de linhas da sua matriz: \"))\n",
106 | " coluna = int(input(\"Informe a quantidade de colunas de sua matriz: \"))\n",
107 | "\n",
108 | " # inicializando a matriz com seu devido tamanho\n",
109 | " matriz = np.empty([linha,coluna], dtype = float)\n",
110 | "\n",
111 | " # estrutura de repetição for que permite introduzir os elementos da matriz\n",
112 | " for i in range(0, linha):\n",
113 | " for j in range(0, coluna):\n",
114 | " matriz[i][j] = float(input(\"Insira o elemento [{}][{}] da matriz: \".format(i + 1, j + 1)))\n",
115 | "\n",
116 | " # imprime a matriz digitada na tela\n",
117 | " print(\"\\nA matriz digitada é:\\n\\n{}\\n\\n\".format(matriz))\n",
118 | "\n",
119 | " # calcula a matriz inversa ou retorna uma mensagem de aviso que a matriz não possui inversa\n",
120 | " if(np.linalg.det(matriz) != 0):\n",
121 | " inversa = np.linalg.pinv(matriz)\n",
122 | " #imprime a matriz inversa\n",
123 | " print(\"A matriz inversa é:\\n\\n{}\\n\\n\".format(inversa))\n",
124 | " else:\n",
125 | " print(\"\\nA matriz não é inversível.\")\n",
126 | " \n",
127 | " # função não retorna nenhum valor\n",
128 | " return None"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": 3,
134 | "metadata": {},
135 | "outputs": [
136 | {
137 | "name": "stdout",
138 | "output_type": "stream",
139 | "text": [
140 | "Progama que calcula a matriz inversa\n"
141 | ]
142 | },
143 | {
144 | "name": "stdin",
145 | "output_type": "stream",
146 | "text": [
147 | "Informe a quantidade de linhas da sua matriz: 3\n",
148 | "Informe a quantidade de colunas de sua matriz: 3\n",
149 | "Insira o elemento [1][1] da matriz: 1\n",
150 | "Insira o elemento [1][2] da matriz: 5\n",
151 | "Insira o elemento [1][3] da matriz: 6\n",
152 | "Insira o elemento [2][1] da matriz: 2\n",
153 | "Insira o elemento [2][2] da matriz: 5\n",
154 | "Insira o elemento [2][3] da matriz: 8\n",
155 | "Insira o elemento [3][1] da matriz: 2\n",
156 | "Insira o elemento [3][2] da matriz: 5\n",
157 | "Insira o elemento [3][3] da matriz: 7\n"
158 | ]
159 | },
160 | {
161 | "name": "stdout",
162 | "output_type": "stream",
163 | "text": [
164 | "\n",
165 | "A matriz digitada é:\n",
166 | "\n",
167 | "[[1. 5. 6.]\n",
168 | " [2. 5. 8.]\n",
169 | " [2. 5. 7.]]\n",
170 | "\n",
171 | "\n",
172 | "A matriz inversa é:\n",
173 | "\n",
174 | "[[-1.00000000e+00 -1.00000000e+00 2.00000000e+00]\n",
175 | " [ 4.00000000e-01 -1.00000000e+00 8.00000000e-01]\n",
176 | " [-1.58676765e-16 1.00000000e+00 -1.00000000e+00]]\n",
177 | "\n",
178 | "\n"
179 | ]
180 | }
181 | ],
182 | "source": [
183 | "# imprimindo a função inversa\n",
184 | "inversa()"
185 | ]
186 | },
187 | {
188 | "cell_type": "markdown",
189 | "metadata": {},
190 | "source": [
191 | "### Alguma Dúvida? Entre em Contato Comigo:"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);"
199 | ]
200 | }
201 | ],
202 | "metadata": {
203 | "kernelspec": {
204 | "display_name": "Python 3",
205 | "language": "python",
206 | "name": "python3"
207 | },
208 | "language_info": {
209 | "codemirror_mode": {
210 | "name": "ipython",
211 | "version": 3
212 | },
213 | "file_extension": ".py",
214 | "mimetype": "text/x-python",
215 | "name": "python",
216 | "nbconvert_exporter": "python",
217 | "pygments_lexer": "ipython3",
218 | "version": "3.7.4"
219 | }
220 | },
221 | "nbformat": 4,
222 | "nbformat_minor": 4
223 | }
224 |
--------------------------------------------------------------------------------
/Conteúdo H - Determinante/prog08_Determinante.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Determinante "
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Em matemática, determinante é uma função matricial que associa a cada matriz quadrada um escalar. Essa função transforma essa matriz em um número real. Esta função permite saber se a matriz tem ou não inversa, pois as que não têm são precisamente aquelas cujo determinante é igual a 0. O cálculo de determinantes está ligado com o conjunto solução de um sistema linear, pois se o cálculo da matriz dos coeficientes de um sistema de equações lineares, onde o número de equações é igual o número de incógnitas (uma matriz quadrada) for um valor diferente de zero, possuímos uma única solução para o sistema, caso o valor do determinante for zero, temos um sistema possível indeterminado ou impossível."
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "# Importa Funções da biblioteca Numpy\n",
24 | "import numpy as np "
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": 2,
30 | "metadata": {},
31 | "outputs": [],
32 | "source": [
33 | "# função que calcula o determinante de uma matriz\n",
34 | "def determinante():\n",
35 | " \n",
36 | " # Recebe a ordem da matriz\n",
37 | " qtd = int(input('Informe o ordem da matriz: ')) \n",
38 | " \n",
39 | " # Inicializa a matriz, ainda com 'lixo de endereços de memória' nele\n",
40 | " matriz = np.empty([qtd, qtd], dtype = float) \n",
41 | " print('\\n')\n",
42 | "\n",
43 | " #Adiciona elementos na matriz\n",
44 | " for i in range(0, qtd):\n",
45 | " for j in range(0, qtd):\n",
46 | " matriz[i][j] = float(input('Digite [{}][{}] da matriz: '.format(i + 1, j + 1)))\n",
47 | "\n",
48 | " #Imprime a matriz\n",
49 | " print('\\nA matriz é:\\n', matriz)\n",
50 | "\n",
51 | " #a variável 'determinante' recebe o determinante da matriz\n",
52 | " determinante = np.linalg.det(matriz)\n",
53 | "\n",
54 | " #Imprime o determinante\n",
55 | " print('\\nO determinante da matriz é: {:.2f}.'.format(determinante))\n",
56 | " \n",
57 | " # função não retorna nada\n",
58 | " return None"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": 3,
64 | "metadata": {},
65 | "outputs": [
66 | {
67 | "name": "stdin",
68 | "output_type": "stream",
69 | "text": [
70 | "Informe o ordem da matriz: 3\n"
71 | ]
72 | },
73 | {
74 | "name": "stdout",
75 | "output_type": "stream",
76 | "text": [
77 | "\n",
78 | "\n"
79 | ]
80 | },
81 | {
82 | "name": "stdin",
83 | "output_type": "stream",
84 | "text": [
85 | "Digite [1][1] da matriz: 1\n",
86 | "Digite [1][2] da matriz: 2\n",
87 | "Digite [1][3] da matriz: 3\n",
88 | "Digite [2][1] da matriz: 3\n",
89 | "Digite [2][2] da matriz: 4\n",
90 | "Digite [2][3] da matriz: 4\n",
91 | "Digite [3][1] da matriz: 7\n",
92 | "Digite [3][2] da matriz: 8\n",
93 | "Digite [3][3] da matriz: 9\n"
94 | ]
95 | },
96 | {
97 | "name": "stdout",
98 | "output_type": "stream",
99 | "text": [
100 | "\n",
101 | "A matriz é:\n",
102 | " [[1. 2. 3.]\n",
103 | " [3. 4. 4.]\n",
104 | " [7. 8. 9.]]\n",
105 | "\n",
106 | "O determinante da matriz é: -6.00.\n"
107 | ]
108 | }
109 | ],
110 | "source": [
111 | "# imprimindo a função determinante\n",
112 | "determinante()"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {},
118 | "source": [
119 | "### Alguma Dúvida? Entre em Contato Comigo:"
120 | ]
121 | },
122 | {
123 | "cell_type": "markdown",
124 | "metadata": {},
125 | "source": [
126 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);"
127 | ]
128 | }
129 | ],
130 | "metadata": {
131 | "kernelspec": {
132 | "display_name": "Python 3",
133 | "language": "python",
134 | "name": "python3"
135 | },
136 | "language_info": {
137 | "codemirror_mode": {
138 | "name": "ipython",
139 | "version": 3
140 | },
141 | "file_extension": ".py",
142 | "mimetype": "text/x-python",
143 | "name": "python",
144 | "nbconvert_exporter": "python",
145 | "pygments_lexer": "ipython3",
146 | "version": "3.7.4"
147 | }
148 | },
149 | "nbformat": 4,
150 | "nbformat_minor": 4
151 | }
152 |
--------------------------------------------------------------------------------
/Conteúdo I - Sistemas Lineares/prog09_SistemasLineares.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Sistemas Lineares\n",
8 | "#### Sistemas lineares é um conjunto de equações lineares, com m equações e n incógnitas. A solução de um sistema linear é a solução de todas as equações lineares."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "##### Referência: Álgebra Linear com aplicações / Anton Howard e Chris Rorres; trad. Claus Ivo Doering. - 8. ed. - Porto Alegre: Bookman, 2001."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "### Sistemas Lineares:"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "Um conjunto finito de equações lineares nas variáveis $x_{1}$, $x_{2}$, ..., $x_{n}$ é chamado um **sistema de equações lineares** ou um **sistema linear**. Uma sequência de números $s_{1}$, $s_{2}$, ..., $s_{n}$ é chamado uma **solução do sistema** se $x_{1}$ = $s_{1}$, $x_{2} = s_{2}$, ..., $x_{n}$ = $s_{n}$ é uma solução de cada equação do sistema. "
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "Um sistema de equações que não possui solução é chamado **inconsistente**; se existir pelo menos uma solução do sistema, dizemos que ele é **consistente**."
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "> Todo sistema de equações lineares tem ou nenhuma solução, ou exatamente uma, ou então uma infinidade de soluções."
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "### Matrizes Aumentadas"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "Se nós mantivermos guardado na memória a localização dos sinais de soma, das variáveis e das constantes, poderemos abreviar a escrita de um sistema de m equações lineares em n incógnitas para:"
58 | ]
59 | },
60 | {
61 | "cell_type": "markdown",
62 | "metadata": {},
63 | "source": [
64 | "$\\begin{bmatrix}\n",
65 | " a_{11} & a_{12} & ... & a_{1n} & b_{1} \\\\\n",
66 | " a_{21} & a_{22} & ... & a_{2n} & b_{2} \\\\\n",
67 | " : & : & : & : & : \\\\\n",
68 | " a_{m1} & a_{m2} & ... & a_{mn} & b_{m} \\\\\n",
69 | " \\end{bmatrix}$"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "Esta é a chamada **matriz aumentada** do sistema. "
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "### Exemplo: Resolvendo Sistemas Lineares com Python"
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": [
90 | "Vamos definir um Sistema do tipo:"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "metadata": {},
96 | "source": [
97 | "\n",
98 | "- a + b + c + d + e + f = 21\n",
99 | "- 10a + 2b + 3c + 4d +5e + f = 70\n",
100 | "- a + b + 2c + 4d + e + f = 36\n",
101 | "- 2a + 7b + c + d + 10e + 2f = 85 \n",
102 | "- 3a + b + c + d + 20e + f = 118\n",
103 | "- 2a + 6b + c + 4d + 5e + f = 64"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "Manualmente resolver tal processo seria muito custoso, poderiamos resolver diagonalizando a matriz aumentando nesse caso. Entretanto, computacionalmente, podemos usar a ideia de matriz inversa a nosso favor para obter as soluções de qualquer tipo de sistema linear. Vejamos como fazer tal processo abaixo:"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "Podemos representar o sistema linear acima utilizando matrizes:"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "$$\\begin{bmatrix}\n",
125 | " 1 & 1 & 1 & 1 & 1 & 1\\\\\n",
126 | " 10 & 2 & 3 & 4 & 5 & 1\\\\\n",
127 | " 1 & 1 & 2 & 4 & 1 & 1\\\\\n",
128 | " 2 & 7 & 1 & 1 & 10 & 2\\\\\n",
129 | " 3 & 1 & 1 & 1 & 20 & 1\\\\\n",
130 | " 2 & 6 & 1 & 4 & 5 & 1\\\\\n",
131 | " \\end{bmatrix}.\\begin{bmatrix}\n",
132 | " a_{1} \\\\\n",
133 | " b_{1} \\\\\n",
134 | " c_{1} \\\\\n",
135 | " d_{1} \\\\\n",
136 | " e_{1} \\\\\n",
137 | " f_{1} \\\\\n",
138 | " \\end{bmatrix} = \\begin{bmatrix}\n",
139 | " 21 \\\\\n",
140 | " 70 \\\\\n",
141 | " 36 \\\\\n",
142 | " 85 \\\\\n",
143 | " 118 \\\\\n",
144 | " 64 \\\\\n",
145 | " \\end{bmatrix}$$"
146 | ]
147 | },
148 | {
149 | "cell_type": "markdown",
150 | "metadata": {},
151 | "source": [
152 | "Vamos seguir os seguintes passos para encontrar o conjunto solução desse sistema linear, ou pelo menos uma das soluções dependendo da matriz apresentada."
153 | ]
154 | },
155 | {
156 | "cell_type": "markdown",
157 | "metadata": {},
158 | "source": [
159 | "$$AX = B$$"
160 | ]
161 | },
162 | {
163 | "cell_type": "markdown",
164 | "metadata": {},
165 | "source": [
166 | "$$A.A^{-1}.X = A^{-1}.B$$"
167 | ]
168 | },
169 | {
170 | "cell_type": "markdown",
171 | "metadata": {},
172 | "source": [
173 | "$$X = A^{-1}.B$$"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": 1,
179 | "metadata": {},
180 | "outputs": [],
181 | "source": [
182 | "# importando a biblioteca numpy\n",
183 | "import numpy as np "
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": 2,
189 | "metadata": {},
190 | "outputs": [],
191 | "source": [
192 | "# declarar as matrizes do exemplo acima\n",
193 | "A = np.array([[1,1,1,1,1,1],[10,2,3,4,5,1],[1,1,2,4,1,1],[2,7,1,1,10,2],\n",
194 | " [3,1,1,1,20,1],[2,6,1,4,5,1]])\n",
195 | "B = np.array([[21],[70],[36],[85],[118],[64]])\n",
196 | "\n",
197 | "# Encontrar a inversa de A\n",
198 | "A_I = np.linalg.inv(A) #Função que encontra a matriz inversa\n",
199 | "\n",
200 | "# Encontrando X\n",
201 | "X = np.dot(A_I,B) # Função que realiza mutiplicação entre matrizes sem especificador de tipo\n",
202 | "# X = np.linalg.solve(A,B) #Função alternativa que resolve Sistemas Lineares"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": 3,
208 | "metadata": {},
209 | "outputs": [
210 | {
211 | "name": "stdout",
212 | "output_type": "stream",
213 | "text": [
214 | "[[ 1 1 1 1 1 1]\n",
215 | " [10 2 3 4 5 1]\n",
216 | " [ 1 1 2 4 1 1]\n",
217 | " [ 2 7 1 1 10 2]\n",
218 | " [ 3 1 1 1 20 1]\n",
219 | " [ 2 6 1 4 5 1]]\n"
220 | ]
221 | }
222 | ],
223 | "source": [
224 | "# imprime a matriz A dos coeficientes de X e Y\n",
225 | "print(\"{}\".format(A)) "
226 | ]
227 | },
228 | {
229 | "cell_type": "code",
230 | "execution_count": 4,
231 | "metadata": {},
232 | "outputs": [
233 | {
234 | "name": "stdout",
235 | "output_type": "stream",
236 | "text": [
237 | "[[ 0.5751938 0.07364341 -0.4124031 -0.26511628 0.04341085 0.2503876 ]\n",
238 | " [-0.80775194 0.05426357 0.29612403 0.40465116 -0.13643411 -0.21550388]\n",
239 | " [-3.91627907 0.31395349 2.24186047 1.86976744 -0.44651163 -1.93255814]\n",
240 | " [ 0.97209302 -0.10465116 -0.41395349 -0.62325581 0.14883721 0.64418605]\n",
241 | " [-0.11317829 -0.00775194 0.04341085 0.02790698 0.04806202 -0.02635659]\n",
242 | " [ 4.28992248 -0.32945736 -1.75503876 -1.41395349 0.34263566 1.27984496]]\n"
243 | ]
244 | }
245 | ],
246 | "source": [
247 | "# imprime a matriz A inversa\n",
248 | "print(\"{}\".format(A_I)) "
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": 5,
254 | "metadata": {},
255 | "outputs": [
256 | {
257 | "name": "stdout",
258 | "output_type": "stream",
259 | "text": [
260 | "[[ 21]\n",
261 | " [ 70]\n",
262 | " [ 36]\n",
263 | " [ 85]\n",
264 | " [118]\n",
265 | " [ 64]]\n"
266 | ]
267 | }
268 | ],
269 | "source": [
270 | "# imprime a matriz B resultado dos sistemas lineares\n",
271 | "print(\"{}\".format(B)) "
272 | ]
273 | },
274 | {
275 | "cell_type": "code",
276 | "execution_count": 6,
277 | "metadata": {},
278 | "outputs": [
279 | {
280 | "name": "stdout",
281 | "output_type": "stream",
282 | "text": [
283 | "[[1.]\n",
284 | " [2.]\n",
285 | " [3.]\n",
286 | " [4.]\n",
287 | " [5.]\n",
288 | " [6.]]\n"
289 | ]
290 | }
291 | ],
292 | "source": [
293 | "# imprime a matrix , o conjunto solução desse sistema\n",
294 | "print(\"{}\".format(X)) "
295 | ]
296 | },
297 | {
298 | "cell_type": "markdown",
299 | "metadata": {},
300 | "source": [
301 | "### Alguma Dúvida? Entre em Contato Comigo:"
302 | ]
303 | },
304 | {
305 | "cell_type": "markdown",
306 | "metadata": {},
307 | "source": [
308 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);"
309 | ]
310 | }
311 | ],
312 | "metadata": {
313 | "kernelspec": {
314 | "display_name": "Python 3",
315 | "language": "python",
316 | "name": "python3"
317 | },
318 | "language_info": {
319 | "codemirror_mode": {
320 | "name": "ipython",
321 | "version": 3
322 | },
323 | "file_extension": ".py",
324 | "mimetype": "text/x-python",
325 | "name": "python",
326 | "nbconvert_exporter": "python",
327 | "pygments_lexer": "ipython3",
328 | "version": "3.7.4"
329 | }
330 | },
331 | "nbformat": 4,
332 | "nbformat_minor": 4
333 | }
334 |
--------------------------------------------------------------------------------
/Conteúdo J - Transformações Lineares/plot_helper.py:
--------------------------------------------------------------------------------
1 | # execute essa linha de código para importar as funções do 'plot_helper'
2 |
3 | import numpy
4 | from numpy.linalg import inv, eig
5 | from math import ceil
6 | from matplotlib import pyplot, ticker, get_backend, rc
7 | from mpl_toolkits.mplot3d import Axes3D
8 | from itertools import cycle
9 |
10 | # interactive backends
11 | _int_backends = ['GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg',
12 | 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo',
13 | 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo']
14 | _backend = get_backend() # get current backend name
15 |
16 | # shrink figsize and fontsize when using %matplotlib notebook
17 | if _backend in _int_backends:
18 | fontsize = 4
19 | fig_scale = 0.75
20 | else:
21 | fontsize = 5
22 | fig_scale = 1
23 |
24 | grey = '#808080'
25 | gold = '#cab18c' # x-axis grid
26 | lightblue = '#0096d6' # y-axis grid
27 | green = '#008367' # x-axis basis vector
28 | red = '#E31937' # y-axis basis vector
29 | darkblue = '#004065'
30 |
31 | pink, yellow, orange, purple, brown = '#ef7b9d', '#fbd349', '#ffa500', '#a35cff', '#731d1d'
32 |
33 | quiver_params = {'angles': 'xy',
34 | 'scale_units': 'xy',
35 | 'scale': 1,
36 | 'width': 0.012}
37 |
38 | grid_params = {'linewidth': 0.5,
39 | 'alpha': 0.8}
40 |
41 | def set_rc(func):
42 | def wrapper(*args, **kwargs):
43 | rc('font', family='serif', size=fontsize)
44 | rc('figure', dpi=200)
45 | rc('axes', axisbelow=True, titlesize=5)
46 | rc('lines', linewidth=1)
47 | func(*args, **kwargs)
48 | return wrapper
49 |
50 | @set_rc
51 | def plot_vector(vectors, tails=None):
52 | ''' Draw 2d vectors based on the values of the vectors and the position of their tails.
53 |
54 | Parameters
55 | ----------
56 | vectors : list.
57 | List of 2-element array-like structures, each represents a 2d vector.
58 |
59 | tails : list, optional.
60 | List of 2-element array-like structures, each represents the coordinates of the tail
61 | of the corresponding vector in vectors. If None (default), all tails are set at the
62 | origin (0,0). If len(tails) is 1, all tails are set at the same position. Otherwise,
63 | vectors and tails must have the same length.
64 |
65 | Examples
66 | --------
67 | >>> v = [(1, 3), (3, 3), (4, 6)]
68 | >>> plot_vector(v) # draw 3 vectors with their tails at origin
69 | >>> t = [numpy.array((2, 2))]
70 | >>> plot_vector(v, t) # draw 3 vectors with their tails at (2,2)
71 | >>> t = [[3, 2], [-1, -2], [3, 5]]
72 | >>> plot_vector(v, t) # draw 3 vectors with 3 different tails
73 | '''
74 | vectors = numpy.array(vectors)
75 | assert vectors.shape[1] == 2, "Each vector should have 2 elements."
76 | if tails is not None:
77 | tails = numpy.array(tails)
78 | assert tails.shape[1] == 2, "Each tail should have 2 elements."
79 | else:
80 | tails = numpy.zeros_like(vectors)
81 |
82 | # tile vectors or tails array if needed
83 | nvectors = vectors.shape[0]
84 | ntails = tails.shape[0]
85 | if nvectors == 1 and ntails > 1:
86 | vectors = numpy.tile(vectors, (ntails, 1))
87 | elif ntails == 1 and nvectors > 1:
88 | tails = numpy.tile(tails, (nvectors, 1))
89 | else:
90 | assert tails.shape == vectors.shape, "vectors and tail must have a same shape"
91 |
92 | # calculate xlimit & ylimit
93 | heads = tails + vectors
94 | limit = numpy.max(numpy.abs(numpy.hstack((tails, heads))))
95 | limit = numpy.ceil(limit * 1.2) # add some margins
96 |
97 | figsize = numpy.array([2,2]) * fig_scale
98 | figure, axis = pyplot.subplots(figsize=figsize)
99 | axis.quiver(tails[:,0], tails[:,1], vectors[:,0], vectors[:,1], color=darkblue,
100 | angles='xy', scale_units='xy', scale=1)
101 | axis.set_xlim([-limit, limit])
102 | axis.set_ylim([-limit, limit])
103 | axis.set_aspect('equal')
104 |
105 | # if xticks and yticks of grid do not match, choose the finer one
106 | xticks = axis.get_xticks()
107 | yticks = axis.get_yticks()
108 | dx = xticks[1] - xticks[0]
109 | dy = yticks[1] - yticks[0]
110 | base = max(int(min(dx, dy)), 1) # grid interval is always an integer
111 | loc = ticker.MultipleLocator(base=base)
112 | axis.xaxis.set_major_locator(loc)
113 | axis.yaxis.set_major_locator(loc)
114 | axis.grid(True, **grid_params)
115 |
116 | # show x-y axis in the center, hide frames
117 | axis.spines['left'].set_position('center')
118 | axis.spines['bottom'].set_position('center')
119 | axis.spines['right'].set_color('none')
120 | axis.spines['top'].set_color('none')
121 |
122 | @set_rc
123 | def plot_transformation_helper(axis, matrix, *vectors, unit_vector=True, unit_circle=False, title=None):
124 | """ A helper function to plot the linear transformation defined by a 2x2 matrix.
125 |
126 | Parameters
127 | ----------
128 | axis : class matplotlib.axes.Axes.
129 | The axes to plot on.
130 | matrix : class numpy.ndarray.
131 | The 2x2 matrix to visualize.
132 | *vectors : class numpy.ndarray.
133 | The vector(s) to plot along with the linear transformation. Each array denotes a vector's
134 | coordinates before the transformation and must have a shape of (2,). Accept any number of vectors.
135 |
136 | unit_vector : bool, optional.
137 | Whether to plot unit vectors of the standard basis, default to True.
138 |
139 | unit_circle: bool, optional.
140 | Whether to plot unit circle, default to False.
141 |
142 | title: str, optional.
143 | Title of the plot.
144 | """
145 | assert matrix.shape == (2,2), "the input matrix must have a shape of (2,2)"
146 | grid_range = 20
147 | x = numpy.arange(-grid_range, grid_range+1)
148 | X_, Y_ = numpy.meshgrid(x,x)
149 | I = matrix[:,0]
150 | J = matrix[:,1]
151 | X = I[0]*X_ + J[0]*Y_
152 | Y = I[1]*X_ + J[1]*Y_
153 | origin = numpy.zeros(1)
154 |
155 | # draw grid lines
156 | for i in range(x.size):
157 | axis.plot(X[i,:], Y[i,:], c=gold, **grid_params)
158 | axis.plot(X[:,i], Y[:,i], c=lightblue, **grid_params)
159 |
160 | # draw (transformed) unit vectors
161 | if unit_vector:
162 | axis.quiver(origin, origin, [I[0]], [I[1]], color=green, **quiver_params)
163 | axis.quiver(origin, origin, [J[0]], [J[1]], color=red, **quiver_params)
164 |
165 | # draw optional vectors
166 | color_cycle = cycle([pink, darkblue, orange, purple, brown])
167 | if vectors:
168 | for vector in vectors:
169 | color = next(color_cycle)
170 | vector_ = matrix @ vector.reshape(-1,1)
171 | axis.quiver(origin, origin, [vector_[0]], [vector_[1]], color=color, **quiver_params)
172 |
173 | # draw optional unit circle
174 | if unit_circle:
175 | alpha = numpy.linspace(0, 2*numpy.pi, 41)
176 | circle = numpy.vstack((numpy.cos(alpha), numpy.sin(alpha)))
177 | circle_trans = matrix @ circle
178 | axis.plot(circle_trans[0], circle_trans[1], color=red, lw=0.8)
179 |
180 | # hide frames, set xlimit & ylimit, set title
181 | limit = 4
182 | axis.spines['left'].set_position('center')
183 | axis.spines['bottom'].set_position('center')
184 | axis.spines['left'].set_linewidth(0.3)
185 | axis.spines['bottom'].set_linewidth(0.3)
186 | axis.spines['right'].set_color('none')
187 | axis.spines['top'].set_color('none')
188 | axis.set_xlim([-limit, limit])
189 | axis.set_ylim([-limit, limit])
190 | if title is not None:
191 | axis.set_title(title)
192 |
193 | @set_rc
194 | def plot_linear_transformation(matrix, *vectors, unit_vector=True, unit_circle=False):
195 | """ Plot the linear transformation defined by a 2x2 matrix using the helper
196 | function plot_transformation_helper(). It will create 2 subplots to visualize some
197 | vectors before and after the transformation.
198 |
199 | Parameters
200 | ----------
201 | matrix : class numpy.ndarray.
202 | The 2x2 matrix to visualize.
203 | *vectors : class numpy.ndarray.
204 | The vector(s) to plot along with the linear transformation. Each array denotes a vector's
205 | coordinates before the transformation and must have a shape of (2,). Accept any number of vectors.
206 |
207 | unit_vector : bool, optional.
208 | Whether to plot unit vectors of the standard basis, default to True.
209 |
210 | unit_circle: bool, optional.
211 | Whether to plot unit circle, default to False.
212 |
213 | """
214 | figsize = numpy.array([4,2]) * fig_scale
215 | figure, (axis1, axis2) = pyplot.subplots(1, 2, figsize=figsize)
216 | plot_transformation_helper(axis1, numpy.identity(2), *vectors, unit_vector=unit_vector, unit_circle=unit_circle, title='Antes da Transformação')
217 | plot_transformation_helper(axis2, matrix, *vectors, unit_vector=unit_vector, unit_circle=unit_circle, title='Depois da Transformação')
218 |
219 | @set_rc
220 | def plot_linear_transformations(*matrices, unit_vector=True, unit_circle=False):
221 | """ Plot the linear transformation defined by a sequence of n 2x2 matrices using the helper
222 | function plot_transformation_helper(). It will create n+1 subplots to visualize some
223 | vectors before and after each transformation.
224 | Parameters
225 | ----------
226 | *matrices : class numpy.ndarray.
227 | The 2x2 matrices to visualize. Accept any number of matrices.
228 |
229 | unit_vector : bool, optional.
230 | Whether to plot unit vectors of the standard basis, default to True.
231 |
232 | unit_circle: bool, optional.
233 | Whether to plot unit circle, default to False.
234 |
235 | """
236 | nplots = len(matrices) + 1
237 | nx = 2
238 | ny = ceil(nplots/nx)
239 | figsize = numpy.array([2*nx, 2*ny]) * fig_scale
240 | figure, axes = pyplot.subplots(nx, ny, figsize=figsize)
241 |
242 | for i in range(nplots): # fig_idx
243 | if i == 0:
244 | matrix_trans = numpy.identity(2)
245 | title = 'Antes da Transformação'
246 | else:
247 | matrix_trans = matrices[i-1] @ matrix_trans
248 | if i == 1:
249 | title = 'Depois de {} Trasnformação'.format(i)
250 | else:
251 | title = 'Depois de {} Transformações'.format(i)
252 | plot_transformation_helper(axes[i//nx, i%nx], matrix_trans, unit_vector=unit_vector, unit_circle=unit_circle, title=title)
253 | # hide axes of the extra subplot (only when nplots is an odd number)
254 | if nx*ny > nplots:
255 | axes[-1,-1].axis('off')
256 |
257 | @set_rc
258 | def plot_3d_transformation_helper(axis, matrix, grid=True, unit_sphere=False, title=None):
259 | """ A helper function to plot the linear transformation defined by a 3x3 matrix.
260 |
261 | Parameters
262 | ----------
263 | axis : class matplotlib.axes.Axes.
264 | The axes to plot on.
265 | matrix : class numpy.ndarray.
266 | The 3x3 matrix to visualize.
267 | grid : bool, optional.
268 | Whether to plot 3d grid lines, default to True.
269 |
270 | unit_sphere : bool, optional.
271 | Whether to plot unit sphere, default to False.
272 |
273 | title : str, optional.
274 | Title of the plot.
275 | """
276 | assert matrix.shape == (3,3), "the input matrix must have a shape of (3,3)"
277 | xcolor, ycolor, zcolor = '#0084b6', '#d8a322', '#FF3333'
278 | linewidth = 0.7
279 | if grid:
280 | grid_range = 2
281 | x = numpy.arange(-grid_range, grid_range+1)
282 | X, Y, Z = numpy.meshgrid(x,x,x)
283 | X_new = matrix[0,0]*X + matrix[0,1]*Y + matrix[0,2]*Z
284 | Y_new = matrix[1,0]*X + matrix[1,1]*Y + matrix[1,2]*Z
285 | Z_new = matrix[2,0]*X + matrix[2,1]*Y + matrix[2,2]*Z
286 | for i in range(x.size):
287 | for j in range(x.size):
288 | axis.plot(X_new[:,i,j], Y_new[:,i,j], Z_new[:,i,j], color=xcolor, linewidth=linewidth)
289 | axis.plot(X_new[i,:,j], Y_new[i,:,j], Z_new[i,:,j], color=ycolor, linewidth=linewidth)
290 | axis.plot(X_new[i,j,:], Y_new[i,j,:], Z_new[i,j,:], color=zcolor, linewidth=linewidth)
291 |
292 | if unit_sphere:
293 | u = numpy.linspace(0, 2 * numpy.pi, 100)
294 | v = numpy.linspace(0, numpy.pi, 100)
295 | X = 1 * numpy.outer(numpy.cos(u), numpy.sin(v))
296 | Y = 1 * numpy.outer(numpy.sin(u), numpy.sin(v))
297 | Z = 1 * numpy.outer(numpy.ones(numpy.size(u)), numpy.cos(v))
298 | X_new = matrix[0,0]*X + matrix[0,1]*Y + matrix[0,2]*Z
299 | Y_new = matrix[1,0]*X + matrix[1,1]*Y + matrix[1,2]*Z
300 | Z_new = matrix[2,0]*X + matrix[2,1]*Y + matrix[2,2]*Z
301 | axis.plot_surface(X_new, Y_new, Z_new, rstride=4, cstride=4, linewidth=0, cmap='ocean', alpha=0.6)
302 |
303 | if title is not None:
304 | axis.set_title(title)
305 |
306 | limit = 0
307 | if grid or unit_sphere:
308 | for array in (X_new, Y_new, Z_new):
309 | limit_ = numpy.max(numpy.abs(array))
310 | limit = max(limit, limit_)
311 | else:
312 | limit = 1
313 | axis.set_xlim(-limit, limit)
314 | axis.set_ylim(-limit, limit)
315 | axis.set_zlim(-limit, limit)
316 | # adjust the whitespace between ticks and axes to get a tighter plot
317 | for axis_str in ['x', 'y', 'z']:
318 | axis.tick_params(axis=axis_str, pad=-3)
319 |
320 | @set_rc
321 | def plot_3d_linear_transformation(matrix, grid=True, unit_sphere=False):
322 | """ Plot the linear transformation defined by a 3x3 matrix using the helper
323 | function plot_3d_transformation_helper(). It will create 2 subplots to visualize some
324 | vectors before and after the transformation.
325 |
326 | Parameters
327 | ----------
328 | matrix : class numpy.ndarray.
329 | The 3x3 matrix to visualize.
330 | grid : bool, optional.
331 | Whether to plot 3d grid lines, default to True.
332 |
333 | unit_sphere : bool, optional.
334 | Whether to plot unit sphere, default to False.
335 | """
336 |
337 | figsize = numpy.array([4,2]) * fig_scale
338 | figure = pyplot.figure(figsize=figsize)
339 | axis1 = figure.add_subplot(1, 2, 1, projection='3d')
340 | axis2 = figure.add_subplot(1, 2, 2, projection='3d')
341 | plot_3d_transformation_helper(axis1, numpy.identity(3), grid=grid, unit_sphere=unit_sphere, title='Antes da Transformação')
342 | plot_3d_transformation_helper(axis2, matrix, grid=grid, unit_sphere=unit_sphere, title='Depois da Transformação')
343 |
344 | @set_rc
345 | def plot_3d_linear_transformations(*matrices, grid=False, unit_sphere=False):
346 | """ Plot the linear transformation defined by a sequence of n 3x3 matrices using the helper
347 | function plot_3d_transformation_helper(). It will create n+1 subplots to visualize some
348 | vectors before and after each transformation.
349 |
350 | Parameters
351 | ----------
352 | *matrices : class numpy.ndarray.
353 | The 3x3 matrices to visualize. Accept any number of matrices.
354 | grid : bool, optional.
355 | Whether to plot 3d grid lines, default to False.
356 |
357 | unit_sphere : bool, optional.
358 | Whether to plot unit sphere, default to False.
359 | """
360 | nplots = len(matrices) + 1
361 | nx = 2 # number of figures per row
362 | ny = ceil(nplots/nx) # number of figures per column
363 | figsize = numpy.array([2*nx, 2*ny]) * fig_scale
364 | figure = pyplot.figure(figsize=figsize)
365 |
366 | for i in range(nplots): # fig_idx
367 | axis = figure.add_subplot(ny, nx, i+1, projection='3d')
368 | if i == 0:
369 | matrix_trans = numpy.identity(3)
370 | title = 'Antes da Transformação'
371 | else:
372 | matrix_trans = matrices[i-1] @ matrix_trans
373 | if i == 1:
374 | title = 'Depois de {} Transformação'.format(i)
375 | else:
376 | title = 'Depois de {} Transformações'.format(i)
377 | plot_3d_transformation_helper(axis, matrix_trans, grid=grid, unit_sphere=unit_sphere, title=title)
378 |
379 | @set_rc
380 | def plot_basis_helper(axis, I, J, *vectors, title=None, I_label='i', J_label='j'):
381 | """ A helper function to plot the 2D coordinate system determined by the basis I,J.
382 |
383 | Parameters
384 | ----------
385 | axis : class matplotlib.axes.Axes.
386 | The axes to plot on.
387 | I, J: class numpy.ndarray.
388 | The coordinates of the basis vector in the standard basis.
389 | *vectors : class numpy.ndarray.
390 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
391 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
392 | a shape of (2,). Accept any number of vectors.
393 |
394 | I_label, J_label : str, optional.
395 | Label of the new basis, default to 'i' and 'j'.
396 |
397 | title: str, optional.
398 | Title of the plot.
399 | """
400 | grid_range = 20
401 | x = numpy.arange(-grid_range, grid_range+1)
402 | X_, Y_ = numpy.meshgrid(x,x) # grid coordinates on the new basis
403 | X = I[0]*X_ + J[0]*Y_ # grid coordinates on the standard basis
404 | Y = I[1]*X_ + J[1]*Y_
405 |
406 | # draw origin
407 | origin = numpy.zeros(1)
408 | axis.scatter(origin, origin, c='black', s=3)
409 |
410 | # draw grid lines of the new coordinate system
411 | lw_grid = 0.4
412 | for i in range(x.size):
413 | axis.plot(X[i,:], Y[i,:], c=grey, lw=lw_grid)
414 | axis.plot(X[:,i], Y[:,i], c=grey, lw=lw_grid)
415 |
416 | # highlight new axes (spines)
417 | lw_spine = 0.7
418 | zero_id = numpy.where(x==0)[0][0]
419 | axis.plot(X[zero_id,:], Y[zero_id,:], c=gold, lw=lw_spine)
420 | axis.plot(X[:,zero_id], Y[:,zero_id], c=lightblue, lw=lw_spine)
421 |
422 | # draw basis vectors using quiver plot
423 | axis.quiver(origin, origin, [I[0]], [I[1]], color=gold, **quiver_params)
424 | axis.quiver(origin, origin, [J[0]], [J[1]], color=lightblue, **quiver_params)
425 |
426 | # draw input vector on new coordinate system
427 | bound = 5
428 | if vectors:
429 | for vector in vectors:
430 | M = numpy.transpose(numpy.vstack((I,J)))
431 | vector = M @ vector.reshape(-1,1)
432 | axis.quiver(origin, origin, [vector[0]], [vector[1]], color=red, **quiver_params)
433 | bound = max(ceil(numpy.max(numpy.abs(vector))), bound)
434 |
435 | # hide frames, set xlimit & ylimit, set title
436 | axis.set_xlim([-bound, bound])
437 | axis.set_ylim([-bound, bound])
438 | axis.axis('off')
439 | if title is not None:
440 | axis.set_title(title)
441 |
442 | # add text next to new basis vectors
443 | text_params = {'ha': 'center', 'va': 'center', 'size' : 6}
444 | axis.text((I[0]-J[0])/2*1.1, (I[1]-J[1])/2*1.1, r'${}$'.format(I_label), color=gold, **text_params)
445 | axis.text((J[0]-I[0])/2*1.1, (J[1]-I[1])/2*1.1, r'${}$'.format(J_label), color=lightblue, **text_params)
446 |
447 | @set_rc
448 | def plot_basis(I, J, *vectors):
449 | """ Plot 2d vectors on the coordinates system defined by basis I and J using the helper funtion
450 | plot_basis_helper().
451 |
452 | Parameters
453 | ----------
454 | I, J: class numpy.ndarray.
455 | The coordinates of the basis vector in the standard basis.
456 | *vectors : class numpy.ndarray.
457 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
458 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
459 | a shape of (2,). Accept any number of vectors.
460 | """
461 | figsize = numpy.array([2,2]) * fig_scale
462 | figure, axis = pyplot.subplots(figsize=figsize)
463 | plot_basis_helper(axis, I, J, *vectors)
464 |
465 | @set_rc
466 | def plot_change_basis(I, J, *vectors):
467 | """ Create a side-by-side plot of some vectors both on the standard basis and on the new basis
468 | defined by I and J, using the helper function plot_basis_helper().
469 |
470 | Parameters
471 | ----------
472 | I, J: class numpy.ndarray.
473 | The coordinates of the basis vector in the standard basis.
474 | *vectors : class numpy.ndarray.
475 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
476 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
477 | a shape of (2,). Accept any number of vectors.
478 | """
479 | figsize = numpy.array([4,2]) * fig_scale
480 | figure, (axis1, axis2) = pyplot.subplots(1, 2, figsize=figsize)
481 | M = numpy.transpose(numpy.vstack((I,J)))
482 | M_inv = inv(M)
483 | vectors_ = [ M_inv @ vector.reshape(-1, 1) for vector in vectors ]
484 | plot_basis_helper(axis1, numpy.array([1,0]), numpy.array([0,1]), *vectors, title='standard basis')
485 | plot_basis_helper(axis2, I, J, *vectors_, title='new basis', I_label='a', J_label='b')
486 |
487 | @set_rc
488 | def plot_eigen(matrix):
489 | """ Visualize the eigendecomposition of a 2x2 matrix as a combination of changing basis
490 | and scaling transformation, using the helper function plot_basis_helper().
491 | Parameters
492 | ----------
493 | matrix : class numpy.ndarray.
494 | The 2x2 matrix to visualize.
495 | """
496 | figsize = numpy.array([4,4]) * fig_scale
497 | figure, axes = pyplot.subplots(2, 2, figsize=figsize)
498 |
499 | eigenvalues, eigenvectors = eig(matrix)
500 | C = eigenvectors
501 | D = numpy.diag(eigenvalues)
502 | C_inv = inv(C)
503 |
504 | alpha = numpy.linspace(0, 2*numpy.pi, 41)
505 | circle = numpy.vstack((numpy.cos(alpha), numpy.sin(alpha)))
506 |
507 | plot_basis_helper(axes[0,0], numpy.array([1,0]), numpy.array([0,1]), title=r'coords in standard basis $\mathbf{x}$')
508 | plot_basis_helper(axes[0,1], C[:,0], C[:,1], title=r'change to new basis $C^{-1}\mathbf{x}$', I_label='a', J_label='b')
509 | plot_basis_helper(axes[1,0], C[:,0], C[:,1], title=r'scale along new basis $DC^{-1}\mathbf{x}$', I_label='a', J_label='b')
510 | plot_basis_helper(axes[1,1], numpy.array([1,0]), numpy.array([0,1]), title=r'change back to standard basis $CDC^{-1}\mathbf{x}$')
511 |
512 | circle_trans = matrix @ circle
513 | for axis in axes[0]:
514 | axis.plot(circle[0], circle[1], color=red, lw=0.8)
515 | for axis in axes[1]:
516 | axis.plot(circle_trans[0], circle_trans[1], color=red, lw=0.8)
517 |
518 | if __name__ == "__main__":
519 | pass
520 |
521 | # funções definidas por L Barba e T Wang para uma apresentação no evento SciPy 2019
522 | # aplicação das funções para a aula do professor Edmar Candeia Gurjão feitas por Alysson Machado
--------------------------------------------------------------------------------
/Conteúdo K - Estudo de Sistemas de Equações/plot_helper.py:
--------------------------------------------------------------------------------
1 | # execute essa linha de código para importar as funções do 'plot_helper'
2 |
3 | import numpy
4 | from numpy.linalg import inv, eig
5 | from math import ceil
6 | from matplotlib import pyplot, ticker, get_backend, rc
7 | from mpl_toolkits.mplot3d import Axes3D
8 | from itertools import cycle
9 |
10 | # interactive backends
11 | _int_backends = ['GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg',
12 | 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo',
13 | 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo']
14 | _backend = get_backend() # get current backend name
15 |
16 | # shrink figsize and fontsize when using %matplotlib notebook
17 | if _backend in _int_backends:
18 | fontsize = 4
19 | fig_scale = 0.75
20 | else:
21 | fontsize = 5
22 | fig_scale = 1
23 |
24 | grey = '#808080'
25 | gold = '#cab18c' # x-axis grid
26 | lightblue = '#0096d6' # y-axis grid
27 | green = '#008367' # x-axis basis vector
28 | red = '#E31937' # y-axis basis vector
29 | darkblue = '#004065'
30 |
31 | pink, yellow, orange, purple, brown = '#ef7b9d', '#fbd349', '#ffa500', '#a35cff', '#731d1d'
32 |
33 | quiver_params = {'angles': 'xy',
34 | 'scale_units': 'xy',
35 | 'scale': 1,
36 | 'width': 0.012}
37 |
38 | grid_params = {'linewidth': 0.5,
39 | 'alpha': 0.8}
40 |
41 | def set_rc(func):
42 | def wrapper(*args, **kwargs):
43 | rc('font', family='serif', size=fontsize)
44 | rc('figure', dpi=200)
45 | rc('axes', axisbelow=True, titlesize=5)
46 | rc('lines', linewidth=1)
47 | func(*args, **kwargs)
48 | return wrapper
49 |
50 | @set_rc
51 | def plot_vector(vectors, tails=None):
52 | ''' Draw 2d vectors based on the values of the vectors and the position of their tails.
53 |
54 | Parameters
55 | ----------
56 | vectors : list.
57 | List of 2-element array-like structures, each represents a 2d vector.
58 |
59 | tails : list, optional.
60 | List of 2-element array-like structures, each represents the coordinates of the tail
61 | of the corresponding vector in vectors. If None (default), all tails are set at the
62 | origin (0,0). If len(tails) is 1, all tails are set at the same position. Otherwise,
63 | vectors and tails must have the same length.
64 |
65 | Examples
66 | --------
67 | >>> v = [(1, 3), (3, 3), (4, 6)]
68 | >>> plot_vector(v) # draw 3 vectors with their tails at origin
69 | >>> t = [numpy.array((2, 2))]
70 | >>> plot_vector(v, t) # draw 3 vectors with their tails at (2,2)
71 | >>> t = [[3, 2], [-1, -2], [3, 5]]
72 | >>> plot_vector(v, t) # draw 3 vectors with 3 different tails
73 | '''
74 | vectors = numpy.array(vectors)
75 | assert vectors.shape[1] == 2, "Each vector should have 2 elements."
76 | if tails is not None:
77 | tails = numpy.array(tails)
78 | assert tails.shape[1] == 2, "Each tail should have 2 elements."
79 | else:
80 | tails = numpy.zeros_like(vectors)
81 |
82 | # tile vectors or tails array if needed
83 | nvectors = vectors.shape[0]
84 | ntails = tails.shape[0]
85 | if nvectors == 1 and ntails > 1:
86 | vectors = numpy.tile(vectors, (ntails, 1))
87 | elif ntails == 1 and nvectors > 1:
88 | tails = numpy.tile(tails, (nvectors, 1))
89 | else:
90 | assert tails.shape == vectors.shape, "vectors and tail must have a same shape"
91 |
92 | # calculate xlimit & ylimit
93 | heads = tails + vectors
94 | limit = numpy.max(numpy.abs(numpy.hstack((tails, heads))))
95 | limit = numpy.ceil(limit * 1.2) # add some margins
96 |
97 | figsize = numpy.array([2,2]) * fig_scale
98 | figure, axis = pyplot.subplots(figsize=figsize)
99 | axis.quiver(tails[:,0], tails[:,1], vectors[:,0], vectors[:,1], color=darkblue,
100 | angles='xy', scale_units='xy', scale=1)
101 | axis.set_xlim([-limit, limit])
102 | axis.set_ylim([-limit, limit])
103 | axis.set_aspect('equal')
104 |
105 | # if xticks and yticks of grid do not match, choose the finer one
106 | xticks = axis.get_xticks()
107 | yticks = axis.get_yticks()
108 | dx = xticks[1] - xticks[0]
109 | dy = yticks[1] - yticks[0]
110 | base = max(int(min(dx, dy)), 1) # grid interval is always an integer
111 | loc = ticker.MultipleLocator(base=base)
112 | axis.xaxis.set_major_locator(loc)
113 | axis.yaxis.set_major_locator(loc)
114 | axis.grid(True, **grid_params)
115 |
116 | # show x-y axis in the center, hide frames
117 | axis.spines['left'].set_position('center')
118 | axis.spines['bottom'].set_position('center')
119 | axis.spines['right'].set_color('none')
120 | axis.spines['top'].set_color('none')
121 |
122 | @set_rc
123 | def plot_transformation_helper(axis, matrix, *vectors, unit_vector=True, unit_circle=False, title=None):
124 | """ A helper function to plot the linear transformation defined by a 2x2 matrix.
125 |
126 | Parameters
127 | ----------
128 | axis : class matplotlib.axes.Axes.
129 | The axes to plot on.
130 | matrix : class numpy.ndarray.
131 | The 2x2 matrix to visualize.
132 | *vectors : class numpy.ndarray.
133 | The vector(s) to plot along with the linear transformation. Each array denotes a vector's
134 | coordinates before the transformation and must have a shape of (2,). Accept any number of vectors.
135 |
136 | unit_vector : bool, optional.
137 | Whether to plot unit vectors of the standard basis, default to True.
138 |
139 | unit_circle: bool, optional.
140 | Whether to plot unit circle, default to False.
141 |
142 | title: str, optional.
143 | Title of the plot.
144 | """
145 | assert matrix.shape == (2,2), "the input matrix must have a shape of (2,2)"
146 | grid_range = 20
147 | x = numpy.arange(-grid_range, grid_range+1)
148 | X_, Y_ = numpy.meshgrid(x,x)
149 | I = matrix[:,0]
150 | J = matrix[:,1]
151 | X = I[0]*X_ + J[0]*Y_
152 | Y = I[1]*X_ + J[1]*Y_
153 | origin = numpy.zeros(1)
154 |
155 | # draw grid lines
156 | for i in range(x.size):
157 | axis.plot(X[i,:], Y[i,:], c=gold, **grid_params)
158 | axis.plot(X[:,i], Y[:,i], c=lightblue, **grid_params)
159 |
160 | # draw (transformed) unit vectors
161 | if unit_vector:
162 | axis.quiver(origin, origin, [I[0]], [I[1]], color=green, **quiver_params)
163 | axis.quiver(origin, origin, [J[0]], [J[1]], color=red, **quiver_params)
164 |
165 | # draw optional vectors
166 | color_cycle = cycle([pink, darkblue, orange, purple, brown])
167 | if vectors:
168 | for vector in vectors:
169 | color = next(color_cycle)
170 | vector_ = matrix @ vector.reshape(-1,1)
171 | axis.quiver(origin, origin, [vector_[0]], [vector_[1]], color=color, **quiver_params)
172 |
173 | # draw optional unit circle
174 | if unit_circle:
175 | alpha = numpy.linspace(0, 2*numpy.pi, 41)
176 | circle = numpy.vstack((numpy.cos(alpha), numpy.sin(alpha)))
177 | circle_trans = matrix @ circle
178 | axis.plot(circle_trans[0], circle_trans[1], color=red, lw=0.8)
179 |
180 | # hide frames, set xlimit & ylimit, set title
181 | limit = 4
182 | axis.spines['left'].set_position('center')
183 | axis.spines['bottom'].set_position('center')
184 | axis.spines['left'].set_linewidth(0.3)
185 | axis.spines['bottom'].set_linewidth(0.3)
186 | axis.spines['right'].set_color('none')
187 | axis.spines['top'].set_color('none')
188 | axis.set_xlim([-limit, limit])
189 | axis.set_ylim([-limit, limit])
190 | if title is not None:
191 | axis.set_title(title)
192 |
193 | @set_rc
194 | def plot_linear_transformation(matrix, *vectors, unit_vector=True, unit_circle=False):
195 | """ Plot the linear transformation defined by a 2x2 matrix using the helper
196 | function plot_transformation_helper(). It will create 2 subplots to visualize some
197 | vectors before and after the transformation.
198 |
199 | Parameters
200 | ----------
201 | matrix : class numpy.ndarray.
202 | The 2x2 matrix to visualize.
203 | *vectors : class numpy.ndarray.
204 | The vector(s) to plot along with the linear transformation. Each array denotes a vector's
205 | coordinates before the transformation and must have a shape of (2,). Accept any number of vectors.
206 |
207 | unit_vector : bool, optional.
208 | Whether to plot unit vectors of the standard basis, default to True.
209 |
210 | unit_circle: bool, optional.
211 | Whether to plot unit circle, default to False.
212 |
213 | """
214 | figsize = numpy.array([4,2]) * fig_scale
215 | figure, (axis1, axis2) = pyplot.subplots(1, 2, figsize=figsize)
216 | plot_transformation_helper(axis1, numpy.identity(2), *vectors, unit_vector=unit_vector, unit_circle=unit_circle, title='Antes da Transformação')
217 | plot_transformation_helper(axis2, matrix, *vectors, unit_vector=unit_vector, unit_circle=unit_circle, title='Depois da Transformação')
218 |
219 | @set_rc
220 | def plot_linear_transformations(*matrices, unit_vector=True, unit_circle=False):
221 | """ Plot the linear transformation defined by a sequence of n 2x2 matrices using the helper
222 | function plot_transformation_helper(). It will create n+1 subplots to visualize some
223 | vectors before and after each transformation.
224 | Parameters
225 | ----------
226 | *matrices : class numpy.ndarray.
227 | The 2x2 matrices to visualize. Accept any number of matrices.
228 |
229 | unit_vector : bool, optional.
230 | Whether to plot unit vectors of the standard basis, default to True.
231 |
232 | unit_circle: bool, optional.
233 | Whether to plot unit circle, default to False.
234 |
235 | """
236 | nplots = len(matrices) + 1
237 | nx = 2
238 | ny = ceil(nplots/nx)
239 | figsize = numpy.array([2*nx, 2*ny]) * fig_scale
240 | figure, axes = pyplot.subplots(nx, ny, figsize=figsize)
241 |
242 | for i in range(nplots): # fig_idx
243 | if i == 0:
244 | matrix_trans = numpy.identity(2)
245 | title = 'Antes da Transformação'
246 | else:
247 | matrix_trans = matrices[i-1] @ matrix_trans
248 | if i == 1:
249 | title = 'Depois de {} Trasnformação'.format(i)
250 | else:
251 | title = 'Depois de {} Transformações'.format(i)
252 | plot_transformation_helper(axes[i//nx, i%nx], matrix_trans, unit_vector=unit_vector, unit_circle=unit_circle, title=title)
253 | # hide axes of the extra subplot (only when nplots is an odd number)
254 | if nx*ny > nplots:
255 | axes[-1,-1].axis('off')
256 |
257 | @set_rc
258 | def plot_3d_transformation_helper(axis, matrix, grid=True, unit_sphere=False, title=None):
259 | """ A helper function to plot the linear transformation defined by a 3x3 matrix.
260 |
261 | Parameters
262 | ----------
263 | axis : class matplotlib.axes.Axes.
264 | The axes to plot on.
265 | matrix : class numpy.ndarray.
266 | The 3x3 matrix to visualize.
267 | grid : bool, optional.
268 | Whether to plot 3d grid lines, default to True.
269 |
270 | unit_sphere : bool, optional.
271 | Whether to plot unit sphere, default to False.
272 |
273 | title : str, optional.
274 | Title of the plot.
275 | """
276 | assert matrix.shape == (3,3), "the input matrix must have a shape of (3,3)"
277 | xcolor, ycolor, zcolor = '#0084b6', '#d8a322', '#FF3333'
278 | linewidth = 0.7
279 | if grid:
280 | grid_range = 2
281 | x = numpy.arange(-grid_range, grid_range+1)
282 | X, Y, Z = numpy.meshgrid(x,x,x)
283 | X_new = matrix[0,0]*X + matrix[0,1]*Y + matrix[0,2]*Z
284 | Y_new = matrix[1,0]*X + matrix[1,1]*Y + matrix[1,2]*Z
285 | Z_new = matrix[2,0]*X + matrix[2,1]*Y + matrix[2,2]*Z
286 | for i in range(x.size):
287 | for j in range(x.size):
288 | axis.plot(X_new[:,i,j], Y_new[:,i,j], Z_new[:,i,j], color=xcolor, linewidth=linewidth)
289 | axis.plot(X_new[i,:,j], Y_new[i,:,j], Z_new[i,:,j], color=ycolor, linewidth=linewidth)
290 | axis.plot(X_new[i,j,:], Y_new[i,j,:], Z_new[i,j,:], color=zcolor, linewidth=linewidth)
291 |
292 | if unit_sphere:
293 | u = numpy.linspace(0, 2 * numpy.pi, 100)
294 | v = numpy.linspace(0, numpy.pi, 100)
295 | X = 1 * numpy.outer(numpy.cos(u), numpy.sin(v))
296 | Y = 1 * numpy.outer(numpy.sin(u), numpy.sin(v))
297 | Z = 1 * numpy.outer(numpy.ones(numpy.size(u)), numpy.cos(v))
298 | X_new = matrix[0,0]*X + matrix[0,1]*Y + matrix[0,2]*Z
299 | Y_new = matrix[1,0]*X + matrix[1,1]*Y + matrix[1,2]*Z
300 | Z_new = matrix[2,0]*X + matrix[2,1]*Y + matrix[2,2]*Z
301 | axis.plot_surface(X_new, Y_new, Z_new, rstride=4, cstride=4, linewidth=0, cmap='ocean', alpha=0.6)
302 |
303 | if title is not None:
304 | axis.set_title(title)
305 |
306 | limit = 0
307 | if grid or unit_sphere:
308 | for array in (X_new, Y_new, Z_new):
309 | limit_ = numpy.max(numpy.abs(array))
310 | limit = max(limit, limit_)
311 | else:
312 | limit = 1
313 | axis.set_xlim(-limit, limit)
314 | axis.set_ylim(-limit, limit)
315 | axis.set_zlim(-limit, limit)
316 | # adjust the whitespace between ticks and axes to get a tighter plot
317 | for axis_str in ['x', 'y', 'z']:
318 | axis.tick_params(axis=axis_str, pad=-3)
319 |
320 | @set_rc
321 | def plot_3d_linear_transformation(matrix, grid=True, unit_sphere=False):
322 | """ Plot the linear transformation defined by a 3x3 matrix using the helper
323 | function plot_3d_transformation_helper(). It will create 2 subplots to visualize some
324 | vectors before and after the transformation.
325 |
326 | Parameters
327 | ----------
328 | matrix : class numpy.ndarray.
329 | The 3x3 matrix to visualize.
330 | grid : bool, optional.
331 | Whether to plot 3d grid lines, default to True.
332 |
333 | unit_sphere : bool, optional.
334 | Whether to plot unit sphere, default to False.
335 | """
336 |
337 | figsize = numpy.array([4,2]) * fig_scale
338 | figure = pyplot.figure(figsize=figsize)
339 | axis1 = figure.add_subplot(1, 2, 1, projection='3d')
340 | axis2 = figure.add_subplot(1, 2, 2, projection='3d')
341 | plot_3d_transformation_helper(axis1, numpy.identity(3), grid=grid, unit_sphere=unit_sphere, title='Antes da Transformação')
342 | plot_3d_transformation_helper(axis2, matrix, grid=grid, unit_sphere=unit_sphere, title='Depois da Transformação')
343 |
344 | @set_rc
345 | def plot_3d_linear_transformations(*matrices, grid=False, unit_sphere=False):
346 | """ Plot the linear transformation defined by a sequence of n 3x3 matrices using the helper
347 | function plot_3d_transformation_helper(). It will create n+1 subplots to visualize some
348 | vectors before and after each transformation.
349 |
350 | Parameters
351 | ----------
352 | *matrices : class numpy.ndarray.
353 | The 3x3 matrices to visualize. Accept any number of matrices.
354 | grid : bool, optional.
355 | Whether to plot 3d grid lines, default to False.
356 |
357 | unit_sphere : bool, optional.
358 | Whether to plot unit sphere, default to False.
359 | """
360 | nplots = len(matrices) + 1
361 | nx = 2 # number of figures per row
362 | ny = ceil(nplots/nx) # number of figures per column
363 | figsize = numpy.array([2*nx, 2*ny]) * fig_scale
364 | figure = pyplot.figure(figsize=figsize)
365 |
366 | for i in range(nplots): # fig_idx
367 | axis = figure.add_subplot(ny, nx, i+1, projection='3d')
368 | if i == 0:
369 | matrix_trans = numpy.identity(3)
370 | title = 'Antes da Transformação'
371 | else:
372 | matrix_trans = matrices[i-1] @ matrix_trans
373 | if i == 1:
374 | title = 'Depois de {} Transformação'.format(i)
375 | else:
376 | title = 'Depois de {} Transformações'.format(i)
377 | plot_3d_transformation_helper(axis, matrix_trans, grid=grid, unit_sphere=unit_sphere, title=title)
378 |
379 | @set_rc
380 | def plot_basis_helper(axis, I, J, *vectors, title=None, I_label='i', J_label='j'):
381 | """ A helper function to plot the 2D coordinate system determined by the basis I,J.
382 |
383 | Parameters
384 | ----------
385 | axis : class matplotlib.axes.Axes.
386 | The axes to plot on.
387 | I, J: class numpy.ndarray.
388 | The coordinates of the basis vector in the standard basis.
389 | *vectors : class numpy.ndarray.
390 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
391 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
392 | a shape of (2,). Accept any number of vectors.
393 |
394 | I_label, J_label : str, optional.
395 | Label of the new basis, default to 'i' and 'j'.
396 |
397 | title: str, optional.
398 | Title of the plot.
399 | """
400 | grid_range = 20
401 | x = numpy.arange(-grid_range, grid_range+1)
402 | X_, Y_ = numpy.meshgrid(x,x) # grid coordinates on the new basis
403 | X = I[0]*X_ + J[0]*Y_ # grid coordinates on the standard basis
404 | Y = I[1]*X_ + J[1]*Y_
405 |
406 | # draw origin
407 | origin = numpy.zeros(1)
408 | axis.scatter(origin, origin, c='black', s=3)
409 |
410 | # draw grid lines of the new coordinate system
411 | lw_grid = 0.4
412 | for i in range(x.size):
413 | axis.plot(X[i,:], Y[i,:], c=grey, lw=lw_grid)
414 | axis.plot(X[:,i], Y[:,i], c=grey, lw=lw_grid)
415 |
416 | # highlight new axes (spines)
417 | lw_spine = 0.7
418 | zero_id = numpy.where(x==0)[0][0]
419 | axis.plot(X[zero_id,:], Y[zero_id,:], c=gold, lw=lw_spine)
420 | axis.plot(X[:,zero_id], Y[:,zero_id], c=lightblue, lw=lw_spine)
421 |
422 | # draw basis vectors using quiver plot
423 | axis.quiver(origin, origin, [I[0]], [I[1]], color=gold, **quiver_params)
424 | axis.quiver(origin, origin, [J[0]], [J[1]], color=lightblue, **quiver_params)
425 |
426 | # draw input vector on new coordinate system
427 | bound = 5
428 | if vectors:
429 | for vector in vectors:
430 | M = numpy.transpose(numpy.vstack((I,J)))
431 | vector = M @ vector.reshape(-1,1)
432 | axis.quiver(origin, origin, [vector[0]], [vector[1]], color=red, **quiver_params)
433 | bound = max(ceil(numpy.max(numpy.abs(vector))), bound)
434 |
435 | # hide frames, set xlimit & ylimit, set title
436 | axis.set_xlim([-bound, bound])
437 | axis.set_ylim([-bound, bound])
438 | axis.axis('off')
439 | if title is not None:
440 | axis.set_title(title)
441 |
442 | # add text next to new basis vectors
443 | text_params = {'ha': 'center', 'va': 'center', 'size' : 6}
444 | axis.text((I[0]-J[0])/2*1.1, (I[1]-J[1])/2*1.1, r'${}$'.format(I_label), color=gold, **text_params)
445 | axis.text((J[0]-I[0])/2*1.1, (J[1]-I[1])/2*1.1, r'${}$'.format(J_label), color=lightblue, **text_params)
446 |
447 | @set_rc
448 | def plot_basis(I, J, *vectors):
449 | """ Plot 2d vectors on the coordinates system defined by basis I and J using the helper funtion
450 | plot_basis_helper().
451 |
452 | Parameters
453 | ----------
454 | I, J: class numpy.ndarray.
455 | The coordinates of the basis vector in the standard basis.
456 | *vectors : class numpy.ndarray.
457 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
458 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
459 | a shape of (2,). Accept any number of vectors.
460 | """
461 | figsize = numpy.array([2,2]) * fig_scale
462 | figure, axis = pyplot.subplots(figsize=figsize)
463 | plot_basis_helper(axis, I, J, *vectors)
464 |
465 | @set_rc
466 | def plot_change_basis(I, J, *vectors):
467 | """ Create a side-by-side plot of some vectors both on the standard basis and on the new basis
468 | defined by I and J, using the helper function plot_basis_helper().
469 |
470 | Parameters
471 | ----------
472 | I, J: class numpy.ndarray.
473 | The coordinates of the basis vector in the standard basis.
474 | *vectors : class numpy.ndarray.
475 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
476 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
477 | a shape of (2,). Accept any number of vectors.
478 | """
479 | figsize = numpy.array([4,2]) * fig_scale
480 | figure, (axis1, axis2) = pyplot.subplots(1, 2, figsize=figsize)
481 | M = numpy.transpose(numpy.vstack((I,J)))
482 | M_inv = inv(M)
483 | vectors_ = [ M_inv @ vector.reshape(-1, 1) for vector in vectors ]
484 | plot_basis_helper(axis1, numpy.array([1,0]), numpy.array([0,1]), *vectors, title='standard basis')
485 | plot_basis_helper(axis2, I, J, *vectors_, title='new basis', I_label='a', J_label='b')
486 |
487 | @set_rc
488 | def plot_eigen(matrix):
489 | """ Visualize the eigendecomposition of a 2x2 matrix as a combination of changing basis
490 | and scaling transformation, using the helper function plot_basis_helper().
491 | Parameters
492 | ----------
493 | matrix : class numpy.ndarray.
494 | The 2x2 matrix to visualize.
495 | """
496 | figsize = numpy.array([4,4]) * fig_scale
497 | figure, axes = pyplot.subplots(2, 2, figsize=figsize)
498 |
499 | eigenvalues, eigenvectors = eig(matrix)
500 | C = eigenvectors
501 | D = numpy.diag(eigenvalues)
502 | C_inv = inv(C)
503 |
504 | alpha = numpy.linspace(0, 2*numpy.pi, 41)
505 | circle = numpy.vstack((numpy.cos(alpha), numpy.sin(alpha)))
506 |
507 | plot_basis_helper(axes[0,0], numpy.array([1,0]), numpy.array([0,1]), title=r'coords in standard basis $\mathbf{x}$')
508 | plot_basis_helper(axes[0,1], C[:,0], C[:,1], title=r'change to new basis $C^{-1}\mathbf{x}$', I_label='a', J_label='b')
509 | plot_basis_helper(axes[1,0], C[:,0], C[:,1], title=r'scale along new basis $DC^{-1}\mathbf{x}$', I_label='a', J_label='b')
510 | plot_basis_helper(axes[1,1], numpy.array([1,0]), numpy.array([0,1]), title=r'change back to standard basis $CDC^{-1}\mathbf{x}$')
511 |
512 | circle_trans = matrix @ circle
513 | for axis in axes[0]:
514 | axis.plot(circle[0], circle[1], color=red, lw=0.8)
515 | for axis in axes[1]:
516 | axis.plot(circle_trans[0], circle_trans[1], color=red, lw=0.8)
517 |
518 | if __name__ == "__main__":
519 | pass
520 |
521 | # funções definidas por L Barba e T Wang para uma apresentação no evento SciPy 2019
522 | # aplicação das funções para a aula do professor Edmar Candeia Gurjão feitas por Alysson Machado
--------------------------------------------------------------------------------
/Conteúdo L - Autovalores e Autovetores/prog12_AutovaloresAutovetores.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Calculando Autovalores e Autovetores\n",
8 | "#### Este progama pretendo mostrar um recurso computacional para conseguir calcular autovalores e autovetores a partir de uma matriz de transformação informada. Associados com uma transformação linear T estão os seus autovetores, que, como veremos, são direções especiais para esta transformação T. Por esta razão, são também conhecidos como vetores próprios ou vetores característicos de T. Aparecem em muitas aplicações, pois nos ajudam a entender mais profundamente a transformação linear T."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "##### Referência: Álgebra Linear com aplicações / Anton Howard e Chris Rorres; trad. Claus Ivo Doering. - 8. ed. - Porto Alegre: Bookman, 2001."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "> Se A é uma matriz $n_{x}n$, então um vetor não-nulo **x** em $R^{n}$ é chamado um **autovetor** de A se A**x** é um múltiplo escalar de **x**, ou seja, A**x** = λ**x** para algum escalar λ. O escalar λ é chamado um **autovalor** de A e dizemos que **x** é um **autovetor** associado a λ."
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "Em $R^{2}$ e $R^{3}$, a multiplicação por A manda cada autovetor **x** de A (se houver) sobre a mesma reta pela origem que **x**. Dependendo do sinal e da magnitude do autovalor λ associado a **x**, o operador linear A**x** = λ**x** comprime ou estica **x** por um fator λ, invertendo o sentido no caso de λ negativo."
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 5,
35 | "metadata": {},
36 | "outputs": [
37 | {
38 | "name": "stdout",
39 | "output_type": "stream",
40 | "text": [
41 | "Progama que calcula Autovalores e Autovetores.\n",
42 | "\n"
43 | ]
44 | },
45 | {
46 | "name": "stdin",
47 | "output_type": "stream",
48 | "text": [
49 | "Informe a quantidade de linhas da matriz de transformação: 3\n",
50 | "Informe a quantidade de colunas da matriz de transformação: 3\n"
51 | ]
52 | },
53 | {
54 | "name": "stdout",
55 | "output_type": "stream",
56 | "text": [
57 | "\n",
58 | "\n"
59 | ]
60 | },
61 | {
62 | "name": "stdin",
63 | "output_type": "stream",
64 | "text": [
65 | "Informe o elemento [1][1] da matriz: 3\n",
66 | "Informe o elemento [1][2] da matriz: -1\n",
67 | "Informe o elemento [1][3] da matriz: 1\n",
68 | "Informe o elemento [2][1] da matriz: -1\n",
69 | "Informe o elemento [2][2] da matriz: 5\n",
70 | "Informe o elemento [2][3] da matriz: -1\n",
71 | "Informe o elemento [3][1] da matriz: 1\n",
72 | "Informe o elemento [3][2] da matriz: -1\n",
73 | "Informe o elemento [3][3] da matriz: 3\n"
74 | ]
75 | },
76 | {
77 | "name": "stdout",
78 | "output_type": "stream",
79 | "text": [
80 | "\n",
81 | "\n",
82 | "A matriz digitada é:\n",
83 | "\n",
84 | "[[ 3. -1. 1.]\n",
85 | " [-1. 5. -1.]\n",
86 | " [ 1. -1. 3.]]\n",
87 | "\n",
88 | "\n",
89 | "Autovalores:\n",
90 | "\n",
91 | "[6. 2. 3.]\n",
92 | "\n",
93 | "\n",
94 | "Matriz Diagonal de autovalores:\n",
95 | "\n",
96 | "[[6. 0. 0.]\n",
97 | " [0. 2. 0.]\n",
98 | " [0. 0. 3.]]\n",
99 | "\n",
100 | "\n",
101 | "cada coluna é associada a cada um dos autovalores, respectivamente.\n",
102 | "Autovetores:\n",
103 | "\n",
104 | "[[-4.08248290e-01 7.07106781e-01 5.77350269e-01]\n",
105 | " [ 8.16496581e-01 5.21597494e-16 5.77350269e-01]\n",
106 | " [-4.08248290e-01 -7.07106781e-01 5.77350269e-01]]\n"
107 | ]
108 | }
109 | ],
110 | "source": [
111 | "# importando a biblioteca numpy do Python\n",
112 | "import numpy as np \n",
113 | "\n",
114 | "print(\"Progama que calcula Autovalores e Autovetores.\\n\")\n",
115 | "\n",
116 | "# quantidade de linhas da matriz de transformação\n",
117 | "linha = int(input(\"Informe a quantidade de linhas da matriz de transformação: \"))\n",
118 | "\n",
119 | "#quantidade de colunas da matriz de transformação\n",
120 | "coluna = int(input(\"Informe a quantidade de colunas da matriz de transformação: \"))\n",
121 | "\n",
122 | "# inicializando uma matriz com as dimensões adequadas e de números reais\n",
123 | "matriz = np.empty([linha, coluna], dtype = float)\n",
124 | "\n",
125 | "# indo para a próxima linha\n",
126 | "print(\"\\n\")\n",
127 | "\n",
128 | "# estrutura de repetição for usada para preencher os elementos da matriz\n",
129 | "for i in range(0, linha):\n",
130 | " for j in range(0, coluna):\n",
131 | " matriz[i][j] = float(input(\"Informe o elemento [{}][{}] da matriz: \".format(i + 1, j + 1)))\n",
132 | "\n",
133 | "# imprime a matriz na tela\n",
134 | "print(\"\\n\\nA matriz digitada é:\\n\\n{}\".format(matriz))\n",
135 | "\n",
136 | "if(np.linalg.det(matriz) != 0):\n",
137 | " \n",
138 | " # função responsável por receber os autovalores e autovetores da matriz de transformação\n",
139 | " (autovalores,autovetores) = np.linalg.eig(matriz)\n",
140 | " matrizDiagonal = np.diag(autovalores) # calcula a matriz diagona de autovalores\n",
141 | " \n",
142 | " # imprime na tela os autovalores\n",
143 | " print(\"\\n\\nAutovalores:\\n\\n{}\\n\\n\".format(autovalores))\n",
144 | "\n",
145 | " # imprime na tela a matriz diagonal de autovalores\n",
146 | " print(\"Matriz Diagonal de autovalores:\\n\\n{}\\n\\n\".format(matrizDiagonal))\n",
147 | "\n",
148 | " # imprime na tela os autovetores\n",
149 | " print(\"cada coluna é associada a cada um dos autovalores, respectivamente.\")\n",
150 | " print(\"Autovetores:\\n\\n{}\".format(autovetores))\n",
151 | "else:\n",
152 | " print(\"\\nA matriz não é invertível, dado que det(matriz) == 0.\")"
153 | ]
154 | },
155 | {
156 | "cell_type": "markdown",
157 | "metadata": {},
158 | "source": [
159 | "- Se A é uma matriz $n_{x}n$ e se $T_{A}:R^{n}$ → $R^{n}$ é a multiplicação por A, então as seguintes afirmações são equivalentes:"
160 | ]
161 | },
162 | {
163 | "cell_type": "markdown",
164 | "metadata": {},
165 | "source": [
166 | "|**Afirmações Equivalente**|\n",
167 | "|:------------:|\n",
168 | "|1. A é invertível. |\n",
169 | "|2. A**x** = 0 admite somente a solução trivial.|\n",
170 | "|3. A forma escalonada reduzida por linha de A é $I_{n}$.|\n",
171 | "|4. A pode ser escrita como um produto de matrizes elementares.|\n",
172 | "|5. A**x** = **b** é consistente para cada matriz **b** de tamanho $n_{x}1$.|\n",
173 | "|6. A**x** = **b** tem exatamente uma solução para cada matrix **b** de tamanho $n_{x}n$.|\n",
174 | "|7. det(A) ≠ 0.|\n",
175 | "|8. A imagem de $T_{A}$ é o $R^{n}$.|\n",
176 | "|9. $T_{A}$ é injetora.|\n",
177 | "|10. Os vetores-coluna de A são linearmente independentes.|\n",
178 | "|11. Os vetores-linhas de A são linearmente dependentes.|\n",
179 | "|12. Os vetores-coluna de A geram o $R^{n}$.|\n",
180 | "|13. Os vetores-linhas de A geram o $R^{n}$.|\n",
181 | "|14. Os vetores-coluna de A formam uma base do $R^{n}$.|\n",
182 | "|15. Os vetores-linha de A formam uma base do $R^{n}$.|\n",
183 | "|16. A tem posto n.|\n",
184 | "|17. A tem nulidade 0.|\n",
185 | "|18. O complemento ortogonal do espaço-nulo de A é o $R^{n}$.|\n",
186 | "|19. O complemento ortogonal do espaço-linha de A é {0}.|\n",
187 | "|20. $A^{t}A$ é invertível.|\n",
188 | "|21. λ = 0 não é um autovalor de A.|"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "### Alguma Dúvida? Entre em Contato Comigo:"
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);"
203 | ]
204 | }
205 | ],
206 | "metadata": {
207 | "kernelspec": {
208 | "display_name": "Python 3",
209 | "language": "python",
210 | "name": "python3"
211 | },
212 | "language_info": {
213 | "codemirror_mode": {
214 | "name": "ipython",
215 | "version": 3
216 | },
217 | "file_extension": ".py",
218 | "mimetype": "text/x-python",
219 | "name": "python",
220 | "nbconvert_exporter": "python",
221 | "pygments_lexer": "ipython3",
222 | "version": "3.7.4"
223 | }
224 | },
225 | "nbformat": 4,
226 | "nbformat_minor": 4
227 | }
228 |
--------------------------------------------------------------------------------
/Conteúdo N - Transformando um Círculo em uma Elípse/plot_helper.py:
--------------------------------------------------------------------------------
1 | # execute essa linha de código para importar as funções do 'plot_helper'
2 |
3 | import numpy
4 | from numpy.linalg import inv, eig
5 | from math import ceil
6 | from matplotlib import pyplot, ticker, get_backend, rc
7 | from mpl_toolkits.mplot3d import Axes3D
8 | from itertools import cycle
9 |
10 | # interactive backends
11 | _int_backends = ['GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg',
12 | 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo',
13 | 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo']
14 | _backend = get_backend() # get current backend name
15 |
16 | # shrink figsize and fontsize when using %matplotlib notebook
17 | if _backend in _int_backends:
18 | fontsize = 4
19 | fig_scale = 0.75
20 | else:
21 | fontsize = 5
22 | fig_scale = 1
23 |
24 | grey = '#808080'
25 | gold = '#cab18c' # x-axis grid
26 | lightblue = '#0096d6' # y-axis grid
27 | green = '#008367' # x-axis basis vector
28 | red = '#E31937' # y-axis basis vector
29 | darkblue = '#004065'
30 |
31 | pink, yellow, orange, purple, brown = '#ef7b9d', '#fbd349', '#ffa500', '#a35cff', '#731d1d'
32 |
33 | quiver_params = {'angles': 'xy',
34 | 'scale_units': 'xy',
35 | 'scale': 1,
36 | 'width': 0.012}
37 |
38 | grid_params = {'linewidth': 0.5,
39 | 'alpha': 0.8}
40 |
41 | def set_rc(func):
42 | def wrapper(*args, **kwargs):
43 | rc('font', family='serif', size=fontsize)
44 | rc('figure', dpi=200)
45 | rc('axes', axisbelow=True, titlesize=5)
46 | rc('lines', linewidth=1)
47 | func(*args, **kwargs)
48 | return wrapper
49 |
50 | @set_rc
51 | def plot_vector(vectors, tails=None):
52 | ''' Draw 2d vectors based on the values of the vectors and the position of their tails.
53 |
54 | Parameters
55 | ----------
56 | vectors : list.
57 | List of 2-element array-like structures, each represents a 2d vector.
58 |
59 | tails : list, optional.
60 | List of 2-element array-like structures, each represents the coordinates of the tail
61 | of the corresponding vector in vectors. If None (default), all tails are set at the
62 | origin (0,0). If len(tails) is 1, all tails are set at the same position. Otherwise,
63 | vectors and tails must have the same length.
64 |
65 | Examples
66 | --------
67 | >>> v = [(1, 3), (3, 3), (4, 6)]
68 | >>> plot_vector(v) # draw 3 vectors with their tails at origin
69 | >>> t = [numpy.array((2, 2))]
70 | >>> plot_vector(v, t) # draw 3 vectors with their tails at (2,2)
71 | >>> t = [[3, 2], [-1, -2], [3, 5]]
72 | >>> plot_vector(v, t) # draw 3 vectors with 3 different tails
73 | '''
74 | vectors = numpy.array(vectors)
75 | assert vectors.shape[1] == 2, "Each vector should have 2 elements."
76 | if tails is not None:
77 | tails = numpy.array(tails)
78 | assert tails.shape[1] == 2, "Each tail should have 2 elements."
79 | else:
80 | tails = numpy.zeros_like(vectors)
81 |
82 | # tile vectors or tails array if needed
83 | nvectors = vectors.shape[0]
84 | ntails = tails.shape[0]
85 | if nvectors == 1 and ntails > 1:
86 | vectors = numpy.tile(vectors, (ntails, 1))
87 | elif ntails == 1 and nvectors > 1:
88 | tails = numpy.tile(tails, (nvectors, 1))
89 | else:
90 | assert tails.shape == vectors.shape, "vectors and tail must have a same shape"
91 |
92 | # calculate xlimit & ylimit
93 | heads = tails + vectors
94 | limit = numpy.max(numpy.abs(numpy.hstack((tails, heads))))
95 | limit = numpy.ceil(limit * 1.2) # add some margins
96 |
97 | figsize = numpy.array([2,2]) * fig_scale
98 | figure, axis = pyplot.subplots(figsize=figsize)
99 | axis.quiver(tails[:,0], tails[:,1], vectors[:,0], vectors[:,1], color=darkblue,
100 | angles='xy', scale_units='xy', scale=1)
101 | axis.set_xlim([-limit, limit])
102 | axis.set_ylim([-limit, limit])
103 | axis.set_aspect('equal')
104 |
105 | # if xticks and yticks of grid do not match, choose the finer one
106 | xticks = axis.get_xticks()
107 | yticks = axis.get_yticks()
108 | dx = xticks[1] - xticks[0]
109 | dy = yticks[1] - yticks[0]
110 | base = max(int(min(dx, dy)), 1) # grid interval is always an integer
111 | loc = ticker.MultipleLocator(base=base)
112 | axis.xaxis.set_major_locator(loc)
113 | axis.yaxis.set_major_locator(loc)
114 | axis.grid(True, **grid_params)
115 |
116 | # show x-y axis in the center, hide frames
117 | axis.spines['left'].set_position('center')
118 | axis.spines['bottom'].set_position('center')
119 | axis.spines['right'].set_color('none')
120 | axis.spines['top'].set_color('none')
121 |
122 | @set_rc
123 | def plot_transformation_helper(axis, matrix, *vectors, unit_vector=True, unit_circle=False, title=None):
124 | """ A helper function to plot the linear transformation defined by a 2x2 matrix.
125 |
126 | Parameters
127 | ----------
128 | axis : class matplotlib.axes.Axes.
129 | The axes to plot on.
130 | matrix : class numpy.ndarray.
131 | The 2x2 matrix to visualize.
132 | *vectors : class numpy.ndarray.
133 | The vector(s) to plot along with the linear transformation. Each array denotes a vector's
134 | coordinates before the transformation and must have a shape of (2,). Accept any number of vectors.
135 |
136 | unit_vector : bool, optional.
137 | Whether to plot unit vectors of the standard basis, default to True.
138 |
139 | unit_circle: bool, optional.
140 | Whether to plot unit circle, default to False.
141 |
142 | title: str, optional.
143 | Title of the plot.
144 | """
145 | assert matrix.shape == (2,2), "the input matrix must have a shape of (2,2)"
146 | grid_range = 20
147 | x = numpy.arange(-grid_range, grid_range+1)
148 | X_, Y_ = numpy.meshgrid(x,x)
149 | I = matrix[:,0]
150 | J = matrix[:,1]
151 | X = I[0]*X_ + J[0]*Y_
152 | Y = I[1]*X_ + J[1]*Y_
153 | origin = numpy.zeros(1)
154 |
155 | # draw grid lines
156 | for i in range(x.size):
157 | axis.plot(X[i,:], Y[i,:], c=gold, **grid_params)
158 | axis.plot(X[:,i], Y[:,i], c=lightblue, **grid_params)
159 |
160 | # draw (transformed) unit vectors
161 | if unit_vector:
162 | axis.quiver(origin, origin, [I[0]], [I[1]], color=green, **quiver_params)
163 | axis.quiver(origin, origin, [J[0]], [J[1]], color=red, **quiver_params)
164 |
165 | # draw optional vectors
166 | color_cycle = cycle([pink, darkblue, orange, purple, brown])
167 | if vectors:
168 | for vector in vectors:
169 | color = next(color_cycle)
170 | vector_ = matrix @ vector.reshape(-1,1)
171 | axis.quiver(origin, origin, [vector_[0]], [vector_[1]], color=color, **quiver_params)
172 |
173 | # draw optional unit circle
174 | if unit_circle:
175 | alpha = numpy.linspace(0, 2*numpy.pi, 41)
176 | circle = numpy.vstack((numpy.cos(alpha), numpy.sin(alpha)))
177 | circle_trans = matrix @ circle
178 | axis.plot(circle_trans[0], circle_trans[1], color=red, lw=0.8)
179 |
180 | # hide frames, set xlimit & ylimit, set title
181 | limit = 4
182 | axis.spines['left'].set_position('center')
183 | axis.spines['bottom'].set_position('center')
184 | axis.spines['left'].set_linewidth(0.3)
185 | axis.spines['bottom'].set_linewidth(0.3)
186 | axis.spines['right'].set_color('none')
187 | axis.spines['top'].set_color('none')
188 | axis.set_xlim([-limit, limit])
189 | axis.set_ylim([-limit, limit])
190 | if title is not None:
191 | axis.set_title(title)
192 |
193 | @set_rc
194 | def plot_linear_transformation(matrix, *vectors, unit_vector=True, unit_circle=False):
195 | """ Plot the linear transformation defined by a 2x2 matrix using the helper
196 | function plot_transformation_helper(). It will create 2 subplots to visualize some
197 | vectors before and after the transformation.
198 |
199 | Parameters
200 | ----------
201 | matrix : class numpy.ndarray.
202 | The 2x2 matrix to visualize.
203 | *vectors : class numpy.ndarray.
204 | The vector(s) to plot along with the linear transformation. Each array denotes a vector's
205 | coordinates before the transformation and must have a shape of (2,). Accept any number of vectors.
206 |
207 | unit_vector : bool, optional.
208 | Whether to plot unit vectors of the standard basis, default to True.
209 |
210 | unit_circle: bool, optional.
211 | Whether to plot unit circle, default to False.
212 |
213 | """
214 | figsize = numpy.array([4,2]) * fig_scale
215 | figure, (axis1, axis2) = pyplot.subplots(1, 2, figsize=figsize)
216 | plot_transformation_helper(axis1, numpy.identity(2), *vectors, unit_vector=unit_vector, unit_circle=unit_circle, title='Antes da Transformação')
217 | plot_transformation_helper(axis2, matrix, *vectors, unit_vector=unit_vector, unit_circle=unit_circle, title='Depois da Transformação')
218 |
219 | @set_rc
220 | def plot_linear_transformations(*matrices, unit_vector=True, unit_circle=False):
221 | """ Plot the linear transformation defined by a sequence of n 2x2 matrices using the helper
222 | function plot_transformation_helper(). It will create n+1 subplots to visualize some
223 | vectors before and after each transformation.
224 | Parameters
225 | ----------
226 | *matrices : class numpy.ndarray.
227 | The 2x2 matrices to visualize. Accept any number of matrices.
228 |
229 | unit_vector : bool, optional.
230 | Whether to plot unit vectors of the standard basis, default to True.
231 |
232 | unit_circle: bool, optional.
233 | Whether to plot unit circle, default to False.
234 |
235 | """
236 | nplots = len(matrices) + 1
237 | nx = 2
238 | ny = ceil(nplots/nx)
239 | figsize = numpy.array([2*nx, 2*ny]) * fig_scale
240 | figure, axes = pyplot.subplots(nx, ny, figsize=figsize)
241 |
242 | for i in range(nplots): # fig_idx
243 | if i == 0:
244 | matrix_trans = numpy.identity(2)
245 | title = 'Antes da Transformação'
246 | else:
247 | matrix_trans = matrices[i-1] @ matrix_trans
248 | if i == 1:
249 | title = 'Depois de {} Trasnformação'.format(i)
250 | else:
251 | title = 'Depois de {} Transformações'.format(i)
252 | plot_transformation_helper(axes[i//nx, i%nx], matrix_trans, unit_vector=unit_vector, unit_circle=unit_circle, title=title)
253 | # hide axes of the extra subplot (only when nplots is an odd number)
254 | if nx*ny > nplots:
255 | axes[-1,-1].axis('off')
256 |
257 | @set_rc
258 | def plot_3d_transformation_helper(axis, matrix, grid=True, unit_sphere=False, title=None):
259 | """ A helper function to plot the linear transformation defined by a 3x3 matrix.
260 |
261 | Parameters
262 | ----------
263 | axis : class matplotlib.axes.Axes.
264 | The axes to plot on.
265 | matrix : class numpy.ndarray.
266 | The 3x3 matrix to visualize.
267 | grid : bool, optional.
268 | Whether to plot 3d grid lines, default to True.
269 |
270 | unit_sphere : bool, optional.
271 | Whether to plot unit sphere, default to False.
272 |
273 | title : str, optional.
274 | Title of the plot.
275 | """
276 | assert matrix.shape == (3,3), "the input matrix must have a shape of (3,3)"
277 | xcolor, ycolor, zcolor = '#0084b6', '#d8a322', '#FF3333'
278 | linewidth = 0.7
279 | if grid:
280 | grid_range = 2
281 | x = numpy.arange(-grid_range, grid_range+1)
282 | X, Y, Z = numpy.meshgrid(x,x,x)
283 | X_new = matrix[0,0]*X + matrix[0,1]*Y + matrix[0,2]*Z
284 | Y_new = matrix[1,0]*X + matrix[1,1]*Y + matrix[1,2]*Z
285 | Z_new = matrix[2,0]*X + matrix[2,1]*Y + matrix[2,2]*Z
286 | for i in range(x.size):
287 | for j in range(x.size):
288 | axis.plot(X_new[:,i,j], Y_new[:,i,j], Z_new[:,i,j], color=xcolor, linewidth=linewidth)
289 | axis.plot(X_new[i,:,j], Y_new[i,:,j], Z_new[i,:,j], color=ycolor, linewidth=linewidth)
290 | axis.plot(X_new[i,j,:], Y_new[i,j,:], Z_new[i,j,:], color=zcolor, linewidth=linewidth)
291 |
292 | if unit_sphere:
293 | u = numpy.linspace(0, 2 * numpy.pi, 100)
294 | v = numpy.linspace(0, numpy.pi, 100)
295 | X = 1 * numpy.outer(numpy.cos(u), numpy.sin(v))
296 | Y = 1 * numpy.outer(numpy.sin(u), numpy.sin(v))
297 | Z = 1 * numpy.outer(numpy.ones(numpy.size(u)), numpy.cos(v))
298 | X_new = matrix[0,0]*X + matrix[0,1]*Y + matrix[0,2]*Z
299 | Y_new = matrix[1,0]*X + matrix[1,1]*Y + matrix[1,2]*Z
300 | Z_new = matrix[2,0]*X + matrix[2,1]*Y + matrix[2,2]*Z
301 | axis.plot_surface(X_new, Y_new, Z_new, rstride=4, cstride=4, linewidth=0, cmap='ocean', alpha=0.6)
302 |
303 | if title is not None:
304 | axis.set_title(title)
305 |
306 | limit = 0
307 | if grid or unit_sphere:
308 | for array in (X_new, Y_new, Z_new):
309 | limit_ = numpy.max(numpy.abs(array))
310 | limit = max(limit, limit_)
311 | else:
312 | limit = 1
313 | axis.set_xlim(-limit, limit)
314 | axis.set_ylim(-limit, limit)
315 | axis.set_zlim(-limit, limit)
316 | # adjust the whitespace between ticks and axes to get a tighter plot
317 | for axis_str in ['x', 'y', 'z']:
318 | axis.tick_params(axis=axis_str, pad=-3)
319 |
320 | @set_rc
321 | def plot_3d_linear_transformation(matrix, grid=True, unit_sphere=False):
322 | """ Plot the linear transformation defined by a 3x3 matrix using the helper
323 | function plot_3d_transformation_helper(). It will create 2 subplots to visualize some
324 | vectors before and after the transformation.
325 |
326 | Parameters
327 | ----------
328 | matrix : class numpy.ndarray.
329 | The 3x3 matrix to visualize.
330 | grid : bool, optional.
331 | Whether to plot 3d grid lines, default to True.
332 |
333 | unit_sphere : bool, optional.
334 | Whether to plot unit sphere, default to False.
335 | """
336 |
337 | figsize = numpy.array([4,2]) * fig_scale
338 | figure = pyplot.figure(figsize=figsize)
339 | axis1 = figure.add_subplot(1, 2, 1, projection='3d')
340 | axis2 = figure.add_subplot(1, 2, 2, projection='3d')
341 | plot_3d_transformation_helper(axis1, numpy.identity(3), grid=grid, unit_sphere=unit_sphere, title='Antes da Transformação')
342 | plot_3d_transformation_helper(axis2, matrix, grid=grid, unit_sphere=unit_sphere, title='Depois da Transformação')
343 |
344 | @set_rc
345 | def plot_3d_linear_transformations(*matrices, grid=False, unit_sphere=False):
346 | """ Plot the linear transformation defined by a sequence of n 3x3 matrices using the helper
347 | function plot_3d_transformation_helper(). It will create n+1 subplots to visualize some
348 | vectors before and after each transformation.
349 |
350 | Parameters
351 | ----------
352 | *matrices : class numpy.ndarray.
353 | The 3x3 matrices to visualize. Accept any number of matrices.
354 | grid : bool, optional.
355 | Whether to plot 3d grid lines, default to False.
356 |
357 | unit_sphere : bool, optional.
358 | Whether to plot unit sphere, default to False.
359 | """
360 | nplots = len(matrices) + 1
361 | nx = 2 # number of figures per row
362 | ny = ceil(nplots/nx) # number of figures per column
363 | figsize = numpy.array([2*nx, 2*ny]) * fig_scale
364 | figure = pyplot.figure(figsize=figsize)
365 |
366 | for i in range(nplots): # fig_idx
367 | axis = figure.add_subplot(ny, nx, i+1, projection='3d')
368 | if i == 0:
369 | matrix_trans = numpy.identity(3)
370 | title = 'Antes da Transformação'
371 | else:
372 | matrix_trans = matrices[i-1] @ matrix_trans
373 | if i == 1:
374 | title = 'Depois de {} Transformação'.format(i)
375 | else:
376 | title = 'Depois de {} Transformações'.format(i)
377 | plot_3d_transformation_helper(axis, matrix_trans, grid=grid, unit_sphere=unit_sphere, title=title)
378 |
379 | @set_rc
380 | def plot_basis_helper(axis, I, J, *vectors, title=None, I_label='i', J_label='j'):
381 | """ A helper function to plot the 2D coordinate system determined by the basis I,J.
382 |
383 | Parameters
384 | ----------
385 | axis : class matplotlib.axes.Axes.
386 | The axes to plot on.
387 | I, J: class numpy.ndarray.
388 | The coordinates of the basis vector in the standard basis.
389 | *vectors : class numpy.ndarray.
390 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
391 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
392 | a shape of (2,). Accept any number of vectors.
393 |
394 | I_label, J_label : str, optional.
395 | Label of the new basis, default to 'i' and 'j'.
396 |
397 | title: str, optional.
398 | Title of the plot.
399 | """
400 | grid_range = 20
401 | x = numpy.arange(-grid_range, grid_range+1)
402 | X_, Y_ = numpy.meshgrid(x,x) # grid coordinates on the new basis
403 | X = I[0]*X_ + J[0]*Y_ # grid coordinates on the standard basis
404 | Y = I[1]*X_ + J[1]*Y_
405 |
406 | # draw origin
407 | origin = numpy.zeros(1)
408 | axis.scatter(origin, origin, c='black', s=3)
409 |
410 | # draw grid lines of the new coordinate system
411 | lw_grid = 0.4
412 | for i in range(x.size):
413 | axis.plot(X[i,:], Y[i,:], c=grey, lw=lw_grid)
414 | axis.plot(X[:,i], Y[:,i], c=grey, lw=lw_grid)
415 |
416 | # highlight new axes (spines)
417 | lw_spine = 0.7
418 | zero_id = numpy.where(x==0)[0][0]
419 | axis.plot(X[zero_id,:], Y[zero_id,:], c=gold, lw=lw_spine)
420 | axis.plot(X[:,zero_id], Y[:,zero_id], c=lightblue, lw=lw_spine)
421 |
422 | # draw basis vectors using quiver plot
423 | axis.quiver(origin, origin, [I[0]], [I[1]], color=gold, **quiver_params)
424 | axis.quiver(origin, origin, [J[0]], [J[1]], color=lightblue, **quiver_params)
425 |
426 | # draw input vector on new coordinate system
427 | bound = 5
428 | if vectors:
429 | for vector in vectors:
430 | M = numpy.transpose(numpy.vstack((I,J)))
431 | vector = M @ vector.reshape(-1,1)
432 | axis.quiver(origin, origin, [vector[0]], [vector[1]], color=red, **quiver_params)
433 | bound = max(ceil(numpy.max(numpy.abs(vector))), bound)
434 |
435 | # hide frames, set xlimit & ylimit, set title
436 | axis.set_xlim([-bound, bound])
437 | axis.set_ylim([-bound, bound])
438 | axis.axis('off')
439 | if title is not None:
440 | axis.set_title(title)
441 |
442 | # add text next to new basis vectors
443 | text_params = {'ha': 'center', 'va': 'center', 'size' : 6}
444 | axis.text((I[0]-J[0])/2*1.1, (I[1]-J[1])/2*1.1, r'${}$'.format(I_label), color=gold, **text_params)
445 | axis.text((J[0]-I[0])/2*1.1, (J[1]-I[1])/2*1.1, r'${}$'.format(J_label), color=lightblue, **text_params)
446 |
447 | @set_rc
448 | def plot_basis(I, J, *vectors):
449 | """ Plot 2d vectors on the coordinates system defined by basis I and J using the helper funtion
450 | plot_basis_helper().
451 |
452 | Parameters
453 | ----------
454 | I, J: class numpy.ndarray.
455 | The coordinates of the basis vector in the standard basis.
456 | *vectors : class numpy.ndarray.
457 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
458 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
459 | a shape of (2,). Accept any number of vectors.
460 | """
461 | figsize = numpy.array([2,2]) * fig_scale
462 | figure, axis = pyplot.subplots(figsize=figsize)
463 | plot_basis_helper(axis, I, J, *vectors)
464 |
465 | @set_rc
466 | def plot_change_basis(I, J, *vectors):
467 | """ Create a side-by-side plot of some vectors both on the standard basis and on the new basis
468 | defined by I and J, using the helper function plot_basis_helper().
469 |
470 | Parameters
471 | ----------
472 | I, J: class numpy.ndarray.
473 | The coordinates of the basis vector in the standard basis.
474 | *vectors : class numpy.ndarray.
475 | The vector(s) to plot along with the change of basis. Each array denotes a vector's
476 | coordinates in I-J coordinate system (not in the standard basis). Each vector must have
477 | a shape of (2,). Accept any number of vectors.
478 | """
479 | figsize = numpy.array([4,2]) * fig_scale
480 | figure, (axis1, axis2) = pyplot.subplots(1, 2, figsize=figsize)
481 | M = numpy.transpose(numpy.vstack((I,J)))
482 | M_inv = inv(M)
483 | vectors_ = [ M_inv @ vector.reshape(-1, 1) for vector in vectors ]
484 | plot_basis_helper(axis1, numpy.array([1,0]), numpy.array([0,1]), *vectors, title='standard basis')
485 | plot_basis_helper(axis2, I, J, *vectors_, title='new basis', I_label='a', J_label='b')
486 |
487 | @set_rc
488 | def plot_eigen(matrix):
489 | """ Visualize the eigendecomposition of a 2x2 matrix as a combination of changing basis
490 | and scaling transformation, using the helper function plot_basis_helper().
491 | Parameters
492 | ----------
493 | matrix : class numpy.ndarray.
494 | The 2x2 matrix to visualize.
495 | """
496 | figsize = numpy.array([4,4]) * fig_scale
497 | figure, axes = pyplot.subplots(2, 2, figsize=figsize)
498 |
499 | eigenvalues, eigenvectors = eig(matrix)
500 | C = eigenvectors
501 | D = numpy.diag(eigenvalues)
502 | C_inv = inv(C)
503 |
504 | alpha = numpy.linspace(0, 2*numpy.pi, 41)
505 | circle = numpy.vstack((numpy.cos(alpha), numpy.sin(alpha)))
506 |
507 | plot_basis_helper(axes[0,0], numpy.array([1,0]), numpy.array([0,1]), title=r'coords in standard basis $\mathbf{x}$')
508 | plot_basis_helper(axes[0,1], C[:,0], C[:,1], title=r'change to new basis $C^{-1}\mathbf{x}$', I_label='a', J_label='b')
509 | plot_basis_helper(axes[1,0], C[:,0], C[:,1], title=r'scale along new basis $DC^{-1}\mathbf{x}$', I_label='a', J_label='b')
510 | plot_basis_helper(axes[1,1], numpy.array([1,0]), numpy.array([0,1]), title=r'change back to standard basis $CDC^{-1}\mathbf{x}$')
511 |
512 | circle_trans = matrix @ circle
513 | for axis in axes[0]:
514 | axis.plot(circle[0], circle[1], color=red, lw=0.8)
515 | for axis in axes[1]:
516 | axis.plot(circle_trans[0], circle_trans[1], color=red, lw=0.8)
517 |
518 | if __name__ == "__main__":
519 | pass
520 |
521 | # funções definidas por L Barba e T Wang para uma apresentação no evento SciPy 2019
522 | # aplicação das funções para a aula do professor Edmar Candeia Gurjão feitas por Alysson Machado
--------------------------------------------------------------------------------
/Conteúdo R - Teoria dos Grafos/prog18_TeoriaDosGrafos.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Teoria dos Grafos\n",
8 | "#### Vamos utilizar representações matriciais das relações entre elementos de um conjunto e, através de arítimética matricial, vamos analisar essas relações."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "##### Referência: Álgebra Linear com aplicações / Anton Howard e Chris Rorres; trad. Claus Ivo Doering. - 8. ed. - Porto Alegre: Bookman, 2001."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "### Relações entre membros do conjunto"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "Existem inúmeros exemplos de conjuntos com um número finito de elementos nos quais existe alguma relação entre os elementos do conjunto. Por exemplo, o conjunto poderia consistir de uma coleção de pessoas, animais, países, companhias, equipes esportivas ou cidades; e a relação entre dois elementos A e B de um tal conjunto poderia ser que a pessoa A domina a pessoa B, o animal A alimenta-se do animal B, o país A apoia militarmente o país B, A companhia A vende seus produtos para a companhia B, a equipe A derrota sistematicamente a equipe B ou a cidade A possui um vôo sem escalas para a cidade B."
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "### Exemplo: Influências numa família"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "Uma certa família consiste de uma mãe, um pai, uma filha e dois filhos. Os membros da família exercem influência, ou poder, sobre os outros membros da família da seguinte maneira: a mãe pode influenciar a filha e o filho mais velho; o pai pode influenciar os dois filhos; a filha pode influenciar o pai; o filho mais velho pode influenciar o filho mais novo; o filho mais novo pode influenciar a mãe."
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "Vamos moldar essa ideia de influência:"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "$\\begin{bmatrix}\n",
58 | " [] & Mae & Pai & Filha & Filho Velho & Filho Novo \\\\\n",
59 | " Mae & 0 & 0 & 1 & 1 & 0 \\\\\n",
60 | " \\end{bmatrix}$"
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "$\\begin{bmatrix}\n",
68 | " [] & Mae & Pai & Filha & Filho Velho & Filho Novo \\\\\n",
69 | " Pai & 0 & 0 & 0 & 1 & 1 \\\\\n",
70 | " \\end{bmatrix}$"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "$\\begin{bmatrix}\n",
78 | " [] & Mae & Pai & Filha & Filho Velho & Filho Novo \\\\\n",
79 | " Filha & 0 & 1 & 0 & 0 & 0 \\\\\n",
80 | " \\end{bmatrix}$"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "$\\begin{bmatrix}\n",
88 | " [] & Mae & Pai & Filha & Filho Velho & Filho Novo \\\\\n",
89 | " Filho Velho & 0 & 0 & 0 & 0 & 1 \\\\\n",
90 | " \\end{bmatrix}$"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "metadata": {},
96 | "source": [
97 | "$\\begin{bmatrix}\n",
98 | " [] & Mae & Pai & Filha & Filho Velho & Filho Novo \\\\\n",
99 | " Filho Novo & 1 & 0 & 0 & 0 & 0 \\\\\n",
100 | " \\end{bmatrix}$"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "As entradas em 1 indicam o poder de influência que o objeto da linha tem sobre a coluna, e o 0 é a ausência de influência."
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "A partir disso, podemos montar a matriz:"
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "$$\\begin{bmatrix}\n",
122 | " [] & M & P & FA & FV & FN \\\\\n",
123 | " M & 0 & 0 & 1 & 1 & 0 \\\\\n",
124 | " P & 0 & 0 & 0 & 1 & 1 \\\\\n",
125 | " FA & 0 & 1 & 0 & 0 & 0 \\\\\n",
126 | " FV & 0 & 0 & 0 & 0 & 1 \\\\\n",
127 | " FN & 1 & 0 & 0 & 0 & 0 \\\\\n",
128 | " \\end{bmatrix}$$"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": 39,
134 | "metadata": {},
135 | "outputs": [],
136 | "source": [
137 | "# importando a biblioteca numpy do Python\n",
138 | "import numpy as np "
139 | ]
140 | },
141 | {
142 | "cell_type": "code",
143 | "execution_count": 40,
144 | "metadata": {},
145 | "outputs": [],
146 | "source": [
147 | "# definindo a matriz influenciaFamilia\n",
148 | "influenciaFamilia = np.array([[0,0,1,1,0],[0,0,0,1,1],[0,1,0,0,0],[0,0,0,0,1],[1,0,0,0,0]]) "
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": 41,
154 | "metadata": {},
155 | "outputs": [
156 | {
157 | "name": "stdout",
158 | "output_type": "stream",
159 | "text": [
160 | "A matriz de influência familiar é:\n",
161 | "\n",
162 | "[[0 0 1 1 0]\n",
163 | " [0 0 0 1 1]\n",
164 | " [0 1 0 0 0]\n",
165 | " [0 0 0 0 1]\n",
166 | " [1 0 0 0 0]]\n"
167 | ]
168 | }
169 | ],
170 | "source": [
171 | "# imprimindo a matriz influenciaFamilia\n",
172 | "print(\"A matriz de influência familiar é:\\n\\n{}\".format(influenciaFamilia))"
173 | ]
174 | },
175 | {
176 | "cell_type": "markdown",
177 | "metadata": {},
178 | "source": [
179 | "Por definição as matrizes obedecerão as seguintes propiedades:"
180 | ]
181 | },
182 | {
183 | "cell_type": "markdown",
184 | "metadata": {},
185 | "source": [
186 | "1. Todas entradas são 0 ou 1."
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "2. Todas entradas na diagonal principal são 0."
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {},
199 | "source": [
200 | "No exemplo 1, o pai não pode influenciar diretamente a mãe, ou seja $P -> M$ não é verdadeiro. Mas o pai pode influenciar o filho mais novo, que por sua vez pode influenciar a mãe. Nós escrevemos isto $P -> FN -> M$ e chamamos conexão de de 2 passos de P para M. Analogamente, chamamos $M -> FV$ de conexão de 1 passo, $FA -> FV -> FN -> M$ de conexão de 3 passos, e assim por diante. Vamos considerar, agora, uma técnica para encontrar o número de todas as conexões de r passos (r = 1,2...) de um vértice $P_{i}$ para um vértice $P_{j}$ de um grafo dirido qualquer. (Isto incluirá o caso em que $P_{i}$ e $P_{j}$ são o mesmo vértice). O número de conexões de 1 passo de $P_{i}$ para $P_{j}$ é simplesmente $M{ij}$. Ou seja, há somente zero ou uma conexão de 1 passo de $P_{i}$ para $P_{j}$, dependendo se $m_{ij}$ é zero ou um. Para o número de conexões de 2 passos, nós consideramos o quadrado da matriz de vértices. Se $m_{ij}^{(2)}$ é o (i,j)-ésimo elemento de $M^2$, nós temos:"
201 | ]
202 | },
203 | {
204 | "cell_type": "markdown",
205 | "metadata": {},
206 | "source": [
207 | "- $m_{ij}^{(2)} = m_{i1}m_{1j} + m_{i2}m_{2j} + ... + m_{in}m_{nj}$"
208 | ]
209 | },
210 | {
211 | "cell_type": "markdown",
212 | "metadata": {},
213 | "source": [
214 | "Agora, se $m_{i1} = m_{1j} = 1$, existe uma conexão de 2 passos $P_{i} -> P_{1} -> P_{j}$ de $P_{i}$ para $P_{j}$. No entanto, se $m_{i1}$ ou se $m_{1j}$ é zero, uma tal conexão de 2 passos não é possível. Assim, $P_{i} -> P_{1} -> P_{j}$ é uma conexão de 2 passos se, e somente se, $m_{i1}m_{1j} = 1$. Similarmente, para cada $k = 1, 2,...,n,P_{i} -> P_{k} -> P_{j}$ é uma conexão de 2 passos de $P_{i}$ para $P_{j}$ se, e somente se, o termo $m_{ik}m_{kj}$ é igual a um; caso contrário, o termo é zero."
215 | ]
216 | },
217 | {
218 | "cell_type": "markdown",
219 | "metadata": {},
220 | "source": [
221 | "Um argumento semelhante funcionará para encontrar o número de conexões de 3,4,...,n passos de $P_{i}$ para $P_{j}$."
222 | ]
223 | },
224 | {
225 | "cell_type": "markdown",
226 | "metadata": {},
227 | "source": [
228 | "### Teorema:"
229 | ]
230 | },
231 | {
232 | "cell_type": "markdown",
233 | "metadata": {},
234 | "source": [
235 | "> Seja M a matriz de vértices de um grafo dirigido e seja $m_{ij}^{(r)}$ o (i,j)-ésimo elemento de $M^{r}$. Então $m_{ij}^{(r)}$ é igual ao número de conexões de r passos de $_{i}$ para $P_{j}$."
236 | ]
237 | },
238 | {
239 | "cell_type": "markdown",
240 | "metadata": {},
241 | "source": [
242 | "Vamos utilizar o exemplo acima para ver, qual familiar pode influenciar outrem, de forma indireta."
243 | ]
244 | },
245 | {
246 | "cell_type": "markdown",
247 | "metadata": {},
248 | "source": [
249 | "### Exemplo: Influência na Família por 2 passos"
250 | ]
251 | },
252 | {
253 | "cell_type": "code",
254 | "execution_count": 42,
255 | "metadata": {},
256 | "outputs": [],
257 | "source": [
258 | "# calcula a matriz elevada a segunda potência.\n",
259 | "influenciaFamilia_2passos = np.linalg.matrix_power(influenciaFamilia, 2) "
260 | ]
261 | },
262 | {
263 | "cell_type": "code",
264 | "execution_count": 43,
265 | "metadata": {},
266 | "outputs": [
267 | {
268 | "name": "stdout",
269 | "output_type": "stream",
270 | "text": [
271 | "A matriz com 2 passos é:\n",
272 | "\n",
273 | "[[0 1 0 0 1]\n",
274 | " [1 0 0 0 1]\n",
275 | " [0 0 0 1 1]\n",
276 | " [1 0 0 0 0]\n",
277 | " [0 0 1 1 0]]\n"
278 | ]
279 | }
280 | ],
281 | "source": [
282 | "print(\"A matriz com 2 passos é:\\n\\n{}\".format(influenciaFamilia_2passos)) \n",
283 | "# a matriz abaixo informa quantos caminhos há para se influenciar outra pessoa em 2 passos,\n",
284 | "# levando a consideração que a ordem de influência é da linha para a coluna"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {},
290 | "source": [
291 | "Observe que agora temos uma nova matriz de influência, essa que ocorrerá por dois passos. Veja o caso discutido acima sobre influência indireta para esse exemplo e observe como a teoria funcionou na prática."
292 | ]
293 | },
294 | {
295 | "cell_type": "markdown",
296 | "metadata": {},
297 | "source": [
298 | "### Exemplo: Influência na Família por 3 passos"
299 | ]
300 | },
301 | {
302 | "cell_type": "code",
303 | "execution_count": 44,
304 | "metadata": {},
305 | "outputs": [],
306 | "source": [
307 | "# calcula a matriz elevada a terceira potência.\n",
308 | "influenciaFamilia_3passos = np.linalg.matrix_power(influenciaFamilia,3) "
309 | ]
310 | },
311 | {
312 | "cell_type": "code",
313 | "execution_count": 45,
314 | "metadata": {},
315 | "outputs": [
316 | {
317 | "name": "stdout",
318 | "output_type": "stream",
319 | "text": [
320 | "a matriz com 3 passos é:\n",
321 | "\n",
322 | "[[1 0 0 1 1]\n",
323 | " [1 0 1 1 0]\n",
324 | " [1 0 0 0 1]\n",
325 | " [0 0 1 1 0]\n",
326 | " [0 1 0 0 1]]\n"
327 | ]
328 | }
329 | ],
330 | "source": [
331 | "print(\"a matriz com 3 passos é:\\n\\n{}\".format(influenciaFamilia_3passos)) \n",
332 | "# a matriz abaixo informa quantos caminhos a para se influenciar outra pessoa em 2 passos,\n",
333 | "# levando a consideração que a ordem de influência é da linha para a coluna"
334 | ]
335 | },
336 | {
337 | "cell_type": "markdown",
338 | "metadata": {},
339 | "source": [
340 | "### Exemplo: Rota Aérea"
341 | ]
342 | },
343 | {
344 | "cell_type": "markdown",
345 | "metadata": {},
346 | "source": [
347 | "A matriz abaixo representa o mapa de uma pequena companhia aére que atende a quatro cidades $P_{1}$,$P_{2}$,$P_{3}$ e $P_{4}$. Como grafo dirigido, a matriz é:"
348 | ]
349 | },
350 | {
351 | "cell_type": "markdown",
352 | "metadata": {},
353 | "source": [
354 | "$$\\begin{bmatrix}\n",
355 | " & P_{1} & P_{2} & P_{3} & P_{4} \\\\\n",
356 | " P_{1} & 0 & 1 & 1 & 0 \\\\\n",
357 | " P_{2} & 1 & 0 & 1 & 0 \\\\\n",
358 | " P_{3} & 1 & 0 & 0 & 1 \\\\\n",
359 | " P_{4} & 0 & 1 & 1 & 0 \\\\\n",
360 | " \\end{bmatrix}$$"
361 | ]
362 | },
363 | {
364 | "cell_type": "code",
365 | "execution_count": 46,
366 | "metadata": {},
367 | "outputs": [],
368 | "source": [
369 | "# definindo a matriz rotaAerea\n",
370 | "rotaAerea = np.array([[0,1,1,0], [1,0,1,0] , [1,0,0,1], [0,1,1,0]])"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": 47,
376 | "metadata": {},
377 | "outputs": [
378 | {
379 | "name": "stdout",
380 | "output_type": "stream",
381 | "text": [
382 | "A matriz rotaAerea é:\n",
383 | "\n",
384 | "[[0 1 1 0]\n",
385 | " [1 0 1 0]\n",
386 | " [1 0 0 1]\n",
387 | " [0 1 1 0]]\n"
388 | ]
389 | }
390 | ],
391 | "source": [
392 | "# imprimindo a matriz rotaAerea\n",
393 | "print(\"A matriz rotaAerea é:\\n\\n{}\".format(rotaAerea))"
394 | ]
395 | },
396 | {
397 | "cell_type": "markdown",
398 | "metadata": {},
399 | "source": [
400 | "Se comunicando diretamente temos:"
401 | ]
402 | },
403 | {
404 | "cell_type": "markdown",
405 | "metadata": {},
406 | "source": [
407 | "- $P_{1} -> P_{2}$\n",
408 | "- $P_{1} -> P_{3}$\n",
409 | "- $P_{2} -> P_{1}$\n",
410 | "- $P_{2} -> P_{3}$\n",
411 | "- $P_{3} -> P_{1}$\n",
412 | "- $P_{3} -> P_{4}$\n",
413 | "- $P_{4} -> P_{2}$\n",
414 | "- $P_{4} -> P_{3}$"
415 | ]
416 | },
417 | {
418 | "cell_type": "markdown",
419 | "metadata": {},
420 | "source": [
421 | "Agora vamos ver a comunicação em dois passos:"
422 | ]
423 | },
424 | {
425 | "cell_type": "code",
426 | "execution_count": 48,
427 | "metadata": {},
428 | "outputs": [],
429 | "source": [
430 | "# definindo a matriz de rotaAerea_2passos para uma comunicação em dois passos, elevando-a \n",
431 | "# na segunda potência\n",
432 | "rotaAerea_2passos = np.linalg.matrix_power(rotaAerea,2)"
433 | ]
434 | },
435 | {
436 | "cell_type": "code",
437 | "execution_count": 49,
438 | "metadata": {},
439 | "outputs": [
440 | {
441 | "name": "stdout",
442 | "output_type": "stream",
443 | "text": [
444 | "A matriz com dois passos é:\n",
445 | "\n",
446 | "[[2 0 1 1]\n",
447 | " [1 1 1 1]\n",
448 | " [0 2 2 0]\n",
449 | " [2 0 1 1]]\n"
450 | ]
451 | }
452 | ],
453 | "source": [
454 | "# imprimindo a matriz rotaAerea_2passos com dois passos\n",
455 | "print(\"A matriz com dois passos é:\\n\\n{}\".format(rotaAerea_2passos))"
456 | ]
457 | },
458 | {
459 | "cell_type": "markdown",
460 | "metadata": {},
461 | "source": [
462 | "Agora, analisando os dados dessa matriz, temos que a rota $P_{3}$ tem duas formas de se comunicar com $P_{2}$"
463 | ]
464 | },
465 | {
466 | "cell_type": "markdown",
467 | "metadata": {},
468 | "source": [
469 | "$P_{3} -> P_{1} -> P_{2}$\n",
470 | "###### ou\n",
471 | "$P_{3} -> P_{4} -> P_{2}$"
472 | ]
473 | },
474 | {
475 | "cell_type": "markdown",
476 | "metadata": {},
477 | "source": [
478 | "Ou então há duas formas da rota $P_{3}$ se comunicar com ela mesma, fato impossível na matriz inicial $rotaAerea^{1}$:"
479 | ]
480 | },
481 | {
482 | "cell_type": "markdown",
483 | "metadata": {},
484 | "source": [
485 | "$P_{3} -> P_{1} -> P_{3}$"
486 | ]
487 | },
488 | {
489 | "cell_type": "markdown",
490 | "metadata": {},
491 | "source": [
492 | "ou"
493 | ]
494 | },
495 | {
496 | "cell_type": "markdown",
497 | "metadata": {},
498 | "source": [
499 | "$P_{3} -> P_{4} -> P_{3}$"
500 | ]
501 | },
502 | {
503 | "cell_type": "markdown",
504 | "metadata": {},
505 | "source": [
506 | "E assim sucessivamente para as outras rotas."
507 | ]
508 | },
509 | {
510 | "cell_type": "markdown",
511 | "metadata": {},
512 | "source": [
513 | "Agora vamos ver conexões com 3 passos:"
514 | ]
515 | },
516 | {
517 | "cell_type": "code",
518 | "execution_count": 50,
519 | "metadata": {},
520 | "outputs": [],
521 | "source": [
522 | "# realiza a terceira potência da matriz rotaAerea em rotaAerea_3passos\n",
523 | "rotaAerea_3passos = np.linalg.matrix_power(rotaAerea, 3)"
524 | ]
525 | },
526 | {
527 | "cell_type": "code",
528 | "execution_count": 51,
529 | "metadata": {},
530 | "outputs": [
531 | {
532 | "name": "stdout",
533 | "output_type": "stream",
534 | "text": [
535 | "A matriz com 3 passos é:\n",
536 | "\n",
537 | "[[1 3 3 1]\n",
538 | " [2 2 3 1]\n",
539 | " [4 0 2 2]\n",
540 | " [1 3 3 1]]\n"
541 | ]
542 | }
543 | ],
544 | "source": [
545 | "# imprimindo a matriz rotaAerea com 3 passos de conexão\n",
546 | "print(\"A matriz com 3 passos é:\\n\\n{}\".format(rotaAerea_3passos))"
547 | ]
548 | },
549 | {
550 | "cell_type": "markdown",
551 | "metadata": {},
552 | "source": [
553 | "Agora vamos ver como a rota $P_{1}$ pode se comunicar por 3 passos com a rota $P_{2}$:"
554 | ]
555 | },
556 | {
557 | "cell_type": "markdown",
558 | "metadata": {},
559 | "source": [
560 | "$P_{1} -> P_{3} -> P_{4} -> P_{2}$"
561 | ]
562 | },
563 | {
564 | "cell_type": "markdown",
565 | "metadata": {},
566 | "source": [
567 | "ou"
568 | ]
569 | },
570 | {
571 | "cell_type": "markdown",
572 | "metadata": {},
573 | "source": [
574 | "$P_{1} -> P_{3} -> P_{1} -> P_{2}$"
575 | ]
576 | },
577 | {
578 | "cell_type": "markdown",
579 | "metadata": {},
580 | "source": [
581 | "E de mesmo modo para as outras rotas."
582 | ]
583 | },
584 | {
585 | "cell_type": "markdown",
586 | "metadata": {},
587 | "source": [
588 | "#### Aprenda mais Sobre Teoria dos Grafos"
589 | ]
590 | },
591 | {
592 | "cell_type": "markdown",
593 | "metadata": {},
594 | "source": [
595 | "###### P. Feofiloff, Y. Kohayakawa, Y. Wakabayashi, Uma Introdução Sucinta à Teoria dos Grafos, 2004."
596 | ]
597 | },
598 | {
599 | "cell_type": "markdown",
600 | "metadata": {},
601 | "source": [
602 | "###### J.M.S. Simões Pereira, Matemática Discreta: Grafos, Redes, Aplicações, Ed. Luz da Vida (Portugal), 2009."
603 | ]
604 | },
605 | {
606 | "cell_type": "markdown",
607 | "metadata": {},
608 | "source": [
609 | "### Alguma Dúvida? Entre em Contato Comigo:"
610 | ]
611 | },
612 | {
613 | "cell_type": "markdown",
614 | "metadata": {},
615 | "source": [
616 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);"
617 | ]
618 | }
619 | ],
620 | "metadata": {
621 | "kernelspec": {
622 | "display_name": "Python 3",
623 | "language": "python",
624 | "name": "python3"
625 | },
626 | "language_info": {
627 | "codemirror_mode": {
628 | "name": "ipython",
629 | "version": 3
630 | },
631 | "file_extension": ".py",
632 | "mimetype": "text/x-python",
633 | "name": "python",
634 | "nbconvert_exporter": "python",
635 | "pygments_lexer": "ipython3",
636 | "version": "3.7.4"
637 | }
638 | },
639 | "nbformat": 4,
640 | "nbformat_minor": 4
641 | }
642 |
--------------------------------------------------------------------------------
/Conteúdo S - Cadeias de Markov/prog19_CadeiasDeMarkov.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Cadeias de Markov\n",
8 | "#### Vamos descrever um modelo geral de um sistema que muda de estado para estado. Uma cadeia de Markov é um caso particular de processo estocástico com estados discretos (o parâmetro, em geral o tempo, pode ser discreto ou contínuo) com a propriedade de que a distribuição de probabilidade do próximo estado depende apenas do estado atual e não na sequência de eventos que precederam."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "##### Álgebra Linear com aplicações / Anton Howard e Chris Rorres; trad. Claus Ivo Doering. - 8. ed. - Porto Alegre: Bookman, 2001."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "### Um Processo de Markov"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "Suponha que um sistema físico ou matemático está sofrendo mudanças tais que a cada momento ele pode ocupar um dentre um número infinito de estados. Por exemplo, o tempo de uma certa cidade poderia estar em um dentre três estados possíveis: ensolarado, nublado ou chuvoso; ou então, um indivíduo poderia estar em um dentre quatro estados emocionais possíveis: feliz, triste, irritado ou apreensivo. Suponha que um tal sistema muda com o tempo de um estado para o outro e que em instantes pré-determinados observamos o estado do sistema. Se o estado do sistema em qualquer observação não puder ser predito com certeza, mas se a probabilidade de um certo estado ocorrer puder ser predita unicamente a partir do conhecimento do estado do sistema na observação imediatamente anterior, então o processo de mudança de um estado para o outro é chamado uma cadeia ou um processo de Markov."
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "### Definição"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "Denotamos por **1, 2, ..., k** os **k** estados possíveis de uma cadeia de Markov. A probabilidade de o sistema estar no estado **i** em qualquer observação, se na observação imediatamente precedente estava no estado **j**, é denotada por $p_{ij}$ e é chamada a probabilidade de transição do estado **j** ao estado **i**. A matriz P = [$p_{ij}$] é chamada a **matriz de transição** da cadeia de Markov."
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "Por exemplo, em uma cadeia de Markov de três estados, a matriz de transição tem o formato"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "$ EstadoPrecedente(j)\n",
58 | "\\\\\n",
59 | "\\begin{bmatrix}\n",
60 | " p_{11} & p_{12} & p_{13} \\\\\n",
61 | " p_{21} & p_{22} & p_{23} \\\\\n",
62 | " p_{31} & p_{32} & p_{33} \\\\\n",
63 | " \\end{bmatrix} NovoEstado(i)$"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "Nesta matriz $p_{32}$ é a probabilidade que o sistema vai mudar do estado 2 para o estado 3, $p_{11}$ é a probabilidade que o sistema vai continuar no estado 1 imediatamente depois de ter sido observado no estado 1, e assim por diante."
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "#### Exemplo: Locadora de Automóveis"
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {},
83 | "source": [
84 | "Uma locadora de automóveis tem três lojas de atendimento, denotadas por 1, 2 e 3. Um cliente pode alugar um carro de qualquer uma das três lojas e devolver o carro para qualquer uma das três lojas. O gerente nota que os clientes costuma devolver os carros de acordo com as seguintes probabilidades:"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": 1,
90 | "metadata": {},
91 | "outputs": [],
92 | "source": [
93 | "# importando a biblioteca de funções numpy do Python\n",
94 | "import numpy as np"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": 5,
100 | "metadata": {},
101 | "outputs": [],
102 | "source": [
103 | "# definindo a matriz de transição A\n",
104 | "A = np.array([[80/100, 30/100, 20/100],\n",
105 | " [10/100, 20/100, 60/100],\n",
106 | " [10/100, 50/100, 20/100]])"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": 10,
112 | "metadata": {},
113 | "outputs": [
114 | {
115 | "name": "stdout",
116 | "output_type": "stream",
117 | "text": [
118 | "A matriz de transição A é:\n",
119 | "\n",
120 | "[[0.8 0.3 0.2]\n",
121 | " [0.1 0.2 0.6]\n",
122 | " [0.1 0.5 0.2]]\n"
123 | ]
124 | }
125 | ],
126 | "source": [
127 | "# imprimindo a matriz aluguelCarro\n",
128 | "print(\"A matriz de transição A é:\\n\\n{}\".format(A))"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "Esta é a matriz de transição do sistema se ele for considerado uma cadeia de Markov. A partir desta matriz, a probabilidade que um carro alugado na loja 3 vá ser devolvido na loja 2 é de 60%, a probabilidade que um carro alugado na loja 1 vá ser devolvido na loja 1 é 80%, e assim por diante."
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {},
141 | "source": [
142 | "Adiante vamos trabalhar mais com esse exemplo."
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {},
148 | "source": [
149 | "#### Exemplo: Doações na Universidade"
150 | ]
151 | },
152 | {
153 | "cell_type": "markdown",
154 | "metadata": {},
155 | "source": [
156 | "Conferindo os registros de doações recebidas, a secretaria da associação de ex-alunos de uma universidade norte-americana observa que 80% de seus ex-alunos que contribuem ao fundo da associação em um certo ano também contribuem no ano seguinte e que 30% dos que não contribuem em um certo ano contribuem no ano seguinte. Isto pode ser visto como uma cadeia de Markov de dois estados: o estado 1 corresponde a um ex-aluno que contribui em um ano qualquer e o estado 2 corresponde a um ex-aluno que não contribuiu naquele ano. A matrriz de transição é:"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": 7,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "# definindo a matriz de transição P\n",
166 | "P = np.array([[80/100, 30/100],\n",
167 | " [20/100, 70/100]])"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": 9,
173 | "metadata": {},
174 | "outputs": [
175 | {
176 | "name": "stdout",
177 | "output_type": "stream",
178 | "text": [
179 | "A matriz de transição P é: \n",
180 | "\n",
181 | "[[0.8 0.3]\n",
182 | " [0.2 0.7]]\n"
183 | ]
184 | }
185 | ],
186 | "source": [
187 | "# imprimindo a matriz P\n",
188 | "print(\"A matriz de transição P é: \\n\\n{}\".format(P))"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "Nos exemplos acima, as matrizes de transição das cadeias de Markov têm a propiedade que as entradas em qualquer coluna somam 1. Isto não é acidental. Se **P** = [$P_{ij}$] é a matriz de transição de uma cadeia de Markov qualquer de **k** estados, então para cada **j** nós devemos ter \n",
196 | "$$p_{1j} + p_{2j} + ... p_{kj} = 1$$\n",
197 | "por que se o sistema está no estado **j** em uma observação, é certo que estará em um dos **k** estados possíveis na próxima observação."
198 | ]
199 | },
200 | {
201 | "cell_type": "markdown",
202 | "metadata": {},
203 | "source": [
204 | "Uma matriz com essa propiedade é chamada **matriz estocástica**, **matriz de probabilidade** ou **matriz de Markov**. Pelo que observamos acima, a matriz de transição de uma cadeia de Markov é sempre uma matriz estocástica."
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {},
210 | "source": [
211 | "Em geral, não pode ser determinado com certeza o estado de um sistema em uma cadeia de Markov numa observação arbitrária. O melhor que podemos fazr é especificar probabilidades para cada um dos estados possíveis. Por exemplo, nós podemos descrever o estado possível do sistema em uma certa observação em uma cadeia de Markov com três estados, por um vetor-coluna:"
212 | ]
213 | },
214 | {
215 | "cell_type": "markdown",
216 | "metadata": {},
217 | "source": [
218 | "$$x = \\begin{bmatrix}\n",
219 | " x_{1} \\\\\n",
220 | " x_{2} \\\\\n",
221 | " x_{3} \\\\\n",
222 | " \\end{bmatrix}$$"
223 | ]
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "metadata": {},
228 | "source": [
229 | "Na qual $x_{1}$ é a probabilidade que o sistema está no estado 1, $x_{2}$ é a probabilidade que ele está no estado 2 e $x_{3}$ é a probabilidade que ele está no estado 3. Em geral, temos a seguinte definição:"
230 | ]
231 | },
232 | {
233 | "cell_type": "markdown",
234 | "metadata": {},
235 | "source": [
236 | "> O **vetor-estado** de uma observação de uma cadeia de Markov com **k** estados é um vetor-coluna **x** cujo i-ésimo componente $x_{i}$ é a probabilidade do sistema estar, naquela observação, no i-ésimo estado."
237 | ]
238 | },
239 | {
240 | "cell_type": "markdown",
241 | "metadata": {},
242 | "source": [
243 | "Observe que as entradas em qualquer vetor-estado de uma cadeia de Markov são não-negativas e têm soma 1. (Por que?) Um vetor-coluna com está propiedade é chamado **vetor de probabilidade**."
244 | ]
245 | },
246 | {
247 | "cell_type": "markdown",
248 | "metadata": {},
249 | "source": [
250 | "Suponha agora, que nós sabemos o vetor-estado $x^{(0)}$ de uma cadeia de Markov em alguma observação inicial. O teorema seguinte nos permitirá determinar os vetores-estado\n",
251 | "$$x^{(1)}, x^{(2)}, ..., x^{(n), ...}$$\n",
252 | "nas observações subsequentes."
253 | ]
254 | },
255 | {
256 | "cell_type": "markdown",
257 | "metadata": {},
258 | "source": [
259 | "> **Teorema**: Se *P* é a matriz de transição de uma cadeia de Markov e $x^{(n)}$ é o vetor-estado da n-ésima observação, então $x^{(n + 1)} = Px^{n}$."
260 | ]
261 | },
262 | {
263 | "cell_type": "markdown",
264 | "metadata": {},
265 | "source": [
266 | "A prova deste teorema envolver ideias de teorias da probabilidades e não será dada aqui. Deste teorema, segue que"
267 | ]
268 | },
269 | {
270 | "cell_type": "markdown",
271 | "metadata": {},
272 | "source": [
273 | "| |\n",
274 | "|-----------------------------------------|\n",
275 | "|$$x^{(1)} = PX^{(0)}$$ |\n",
276 | "|$$x^{(2)} = PX^{(1)} = P^{2}x^{(0)}$$ |\n",
277 | "|$$x^{(3)} = PX^{(2)} = P^{3}x^{(0)}$$ |\n",
278 | "|