├── .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 | "\"Open" 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 | "|
|\n", 279 | "|$$x^{(n)} = PX^{(n - 1)} = P^{n}x^{(0)}$$|" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": {}, 285 | "source": [ 286 | "Desta maneira, o vetor-estado inicial $x^{(0)}$ e a matriz de transição **P** determinam $x^{(n)}$ para **n = 1, 2, ...**" 287 | ] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "#### Exemplo: Doação de Universidade" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "metadata": {}, 299 | "source": [ 300 | "A matriz de transição no exemplo 2 era:" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 12, 306 | "metadata": {}, 307 | "outputs": [ 308 | { 309 | "name": "stdout", 310 | "output_type": "stream", 311 | "text": [ 312 | "A matriz de transição P: \n", 313 | "\n", 314 | "[[0.8 0.3]\n", 315 | " [0.2 0.7]]\n" 316 | ] 317 | } 318 | ], 319 | "source": [ 320 | "# imprimindo a matriz P\n", 321 | "print(\"A matriz de transição P: \\n\\n{}\".format(P))" 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "Nós agora iremos construir um registro futuro provável de doações de um novo graduando que não doou no primeiro ano após a formatura. Para um tal graduando, o sistema está, inicialmente, com certeza no estado 2, de modo que o vetor-estado inicial é:" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": 13, 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [ 337 | "# definindo o vetor-estado x\n", 338 | "x = np.array([[0],\n", 339 | " [1]])" 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": 14, 345 | "metadata": {}, 346 | "outputs": [ 347 | { 348 | "name": "stdout", 349 | "output_type": "stream", 350 | "text": [ 351 | "O vetor-estado é: \n", 352 | "\n", 353 | "[[0]\n", 354 | " [1]]\n" 355 | ] 356 | } 357 | ], 358 | "source": [ 359 | "# imprimindo o vetor-estado x\n", 360 | "print(\"O vetor-estado é: \\n\\n{}\".format(x))" 361 | ] 362 | }, 363 | { 364 | "cell_type": "markdown", 365 | "metadata": {}, 366 | "source": [ 367 | "Pelo Teorema acima, nós temos, então," 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": 15, 373 | "metadata": {}, 374 | "outputs": [], 375 | "source": [ 376 | "# função que realizará a mudança de estado até o ano a ser definido\n", 377 | "def estado(matrizTransicao, vetorEstado, transicao):\n", 378 | " \n", 379 | " # estrutura de repetição for de 0 até (anos - 1)\n", 380 | " for indice in range(0, transicao):\n", 381 | " \n", 382 | " # realiza o calculo definido no teorema acima\n", 383 | " vetorEstado = np.dot(matrizTransicao, vetorEstado)\n", 384 | " \n", 385 | " # retorna o vetor estado após sofrer todas as mudanças de estado até o ano informado\n", 386 | " return vetorEstado" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": 16, 392 | "metadata": {}, 393 | "outputs": [ 394 | { 395 | "name": "stdout", 396 | "output_type": "stream", 397 | "text": [ 398 | "O vetor-estado após 1 ano é: \n", 399 | "\n", 400 | "[[0.3]\n", 401 | " [0.7]]\n" 402 | ] 403 | } 404 | ], 405 | "source": [ 406 | "# vetor-estado após 1 ano\n", 407 | "print(\"O vetor-estado após 1 ano é: \\n\\n{}\".format(estado(P, x, transicao = 1)))" 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": {}, 413 | "source": [ 414 | "assim, após 1 ano é esperado que o aluno tenha 30% de chance de doar nesse ano (estado 1) e 70% de chance de não doar nesse ano (estado 2)." 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 17, 420 | "metadata": {}, 421 | "outputs": [ 422 | { 423 | "name": "stdout", 424 | "output_type": "stream", 425 | "text": [ 426 | "O vetor-estado após 8 anos é: \n", 427 | "\n", 428 | "[[0.59765625]\n", 429 | " [0.40234375]]\n" 430 | ] 431 | } 432 | ], 433 | "source": [ 434 | "# vetor-estado após 8 ano\n", 435 | "print(\"O vetor-estado após 8 anos é: \\n\\n{}\".format(estado(P, x, transicao = 8)))" 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 19, 441 | "metadata": {}, 442 | "outputs": [ 443 | { 444 | "name": "stdout", 445 | "output_type": "stream", 446 | "text": [ 447 | "O vetor-estado após 11 ano é: \n", 448 | "\n", 449 | "[[0.59970703]\n", 450 | " [0.40029297]]\n" 451 | ] 452 | } 453 | ], 454 | "source": [ 455 | "# vetor-estado após 11 ano\n", 456 | "print(\"O vetor-estado após 11 ano é: \\n\\n{}\".format(estado(P, x, transicao = 11)))" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "metadata": {}, 462 | "source": [ 463 | "Observe que entre os vetores-estado após 8 anos e 11 anos, a mudança de probabilidade não mudou de forma brusca. Em outras palavras, os vetores-estado convergem a um vetor fixo à medida que cresce o número de observações." 464 | ] 465 | }, 466 | { 467 | "cell_type": "markdown", 468 | "metadata": {}, 469 | "source": [ 470 | "#### Exemplo: Locadora de Automóveis" 471 | ] 472 | }, 473 | { 474 | "cell_type": "markdown", 475 | "metadata": {}, 476 | "source": [ 477 | "Vamos voltar ao exemplo 1 para aplicar os nossos novos conhecimentos." 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 21, 483 | "metadata": {}, 484 | "outputs": [ 485 | { 486 | "name": "stdout", 487 | "output_type": "stream", 488 | "text": [ 489 | "A matriz de transição A do exemplo 1 é: \n", 490 | "\n", 491 | "[[0.8 0.3 0.2]\n", 492 | " [0.1 0.2 0.6]\n", 493 | " [0.1 0.5 0.2]]\n" 494 | ] 495 | } 496 | ], 497 | "source": [ 498 | "# imprimindo a matriz de transição do exemplo 1\n", 499 | "print(\"A matriz de transição A do exemplo 1 é: \\n\\n{}\".format(A))" 500 | ] 501 | }, 502 | { 503 | "cell_type": "markdown", 504 | "metadata": {}, 505 | "source": [ 506 | "Se um carro é inicialmente alugado na loja 2, então o vetor estado inicial é" 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": 22, 512 | "metadata": {}, 513 | "outputs": [], 514 | "source": [ 515 | "# definindo o vetor-estado inicial\n", 516 | "w = np.array([[0],\n", 517 | " [1],\n", 518 | " [0]])" 519 | ] 520 | }, 521 | { 522 | "cell_type": "code", 523 | "execution_count": 23, 524 | "metadata": {}, 525 | "outputs": [ 526 | { 527 | "name": "stdout", 528 | "output_type": "stream", 529 | "text": [ 530 | "O vetor-estado w é: \n", 531 | "\n", 532 | "[[0]\n", 533 | " [1]\n", 534 | " [0]]\n" 535 | ] 536 | } 537 | ], 538 | "source": [ 539 | "# imprimindo o vetor w\n", 540 | "print(\"O vetor-estado w é: \\n\\n{}\".format(w))" 541 | ] 542 | }, 543 | { 544 | "cell_type": "markdown", 545 | "metadata": {}, 546 | "source": [ 547 | " Esse é o vetor-estado no estado 2, o qual indica que o carro foi alugado na loja 2 no aluguel inicial." 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "execution_count": 25, 553 | "metadata": {}, 554 | "outputs": [ 555 | { 556 | "name": "stdout", 557 | "output_type": "stream", 558 | "text": [ 559 | "O vetor-estado na 1º observação é: \n", 560 | "\n", 561 | "[[0.3]\n", 562 | " [0.2]\n", 563 | " [0.5]]\n" 564 | ] 565 | } 566 | ], 567 | "source": [ 568 | "# vetor-estado após a 1º observação\n", 569 | "print(\"O vetor-estado na 1º observação é: \\n\\n{}\".format(estado(A, w, transicao = 1)))" 570 | ] 571 | }, 572 | { 573 | "cell_type": "markdown", 574 | "metadata": {}, 575 | "source": [ 576 | "Após a 1º observação temos 30% de chance do carro ser devolvido na loja 1, 20% de chance na loja 2 e 50% de chance na loja 3. Para a próxima observação, sempre consideramos a observação atual e a relacionamos com a matriz de transição. Então, tendo agora o vetor-estado com as caracteristicas acima do carro ser devolvido nessas lojas, teremos na 2º observação:" 577 | ] 578 | }, 579 | { 580 | "cell_type": "code", 581 | "execution_count": 26, 582 | "metadata": {}, 583 | "outputs": [ 584 | { 585 | "name": "stdout", 586 | "output_type": "stream", 587 | "text": [ 588 | "O vetor-estado na 2º observação é: \n", 589 | "\n", 590 | "[[0.4 ]\n", 591 | " [0.37]\n", 592 | " [0.23]]\n" 593 | ] 594 | } 595 | ], 596 | "source": [ 597 | "# vetor-estado após a 2º observação\n", 598 | "print(\"O vetor-estado na 2º observação é: \\n\\n{}\".format(estado(A, w, transicao = 2)))" 599 | ] 600 | }, 601 | { 602 | "cell_type": "markdown", 603 | "metadata": {}, 604 | "source": [ 605 | "e na 4º observação:" 606 | ] 607 | }, 608 | { 609 | "cell_type": "code", 610 | "execution_count": 27, 611 | "metadata": {}, 612 | "outputs": [ 613 | { 614 | "name": "stdout", 615 | "output_type": "stream", 616 | "text": [ 617 | "O vetor-estado na 4º observação é: \n", 618 | "\n", 619 | "[[0.5114]\n", 620 | " [0.2607]\n", 621 | " [0.2279]]\n" 622 | ] 623 | } 624 | ], 625 | "source": [ 626 | "# vetor-estado após a 4º observação\n", 627 | "print(\"O vetor-estado na 4º observação é: \\n\\n{}\".format(estado(A, w, transicao = 4)))" 628 | ] 629 | }, 630 | { 631 | "cell_type": "markdown", 632 | "metadata": {}, 633 | "source": [ 634 | "Assim, no 4º aluguel de carros, temos a probabilidade de 51% do carro ser devolvido na loja 1, 26% do carro ser devolvido na loja 2 e 22% do carro ser devolvido na loja 3." 635 | ] 636 | }, 637 | { 638 | "cell_type": "code", 639 | "execution_count": 28, 640 | "metadata": {}, 641 | "outputs": [ 642 | { 643 | "name": "stdout", 644 | "output_type": "stream", 645 | "text": [ 646 | "O vetor-estado na 10º observação é: \n", 647 | "\n", 648 | "[[0.556162 ]\n", 649 | " [0.23016171]\n", 650 | " [0.21367629]]\n" 651 | ] 652 | } 653 | ], 654 | "source": [ 655 | "# vetor-estado após a 10º observação\n", 656 | "print(\"O vetor-estado na 10º observação é: \\n\\n{}\".format(estado(A, w, transicao = 10)))" 657 | ] 658 | }, 659 | { 660 | "cell_type": "code", 661 | "execution_count": 29, 662 | "metadata": {}, 663 | "outputs": [ 664 | { 665 | "name": "stdout", 666 | "output_type": "stream", 667 | "text": [ 668 | "O vetor-estado na 11º observação é: \n", 669 | "\n", 670 | "[[0.55671337]\n", 671 | " [0.22985432]\n", 672 | " [0.21343231]]\n" 673 | ] 674 | } 675 | ], 676 | "source": [ 677 | "# vetor-estado após a 11º observação\n", 678 | "print(\"O vetor-estado na 11º observação é: \\n\\n{}\".format(estado(A, w, transicao = 11)))" 679 | ] 680 | }, 681 | { 682 | "cell_type": "markdown", 683 | "metadata": {}, 684 | "source": [ 685 | "> Duas coisas deveriam ser observadas neste exemplo. Em primeiro lugar, não foi necessário saber por quanto tempo o cliente permaneceu com o carro. Ou seja, num processo de Markov o tempo entre as observações não precisa ser regular. Em segundo lugar, os vetores-estado comvergem a um vetor fixo à medida que n cresce, exatamente como no exemplo anterior." 686 | ] 687 | }, 688 | { 689 | "cell_type": "markdown", 690 | "metadata": {}, 691 | "source": [ 692 | "#### Exemplo: Guarda de trânsito" 693 | ] 694 | }, 695 | { 696 | "cell_type": "markdown", 697 | "metadata": {}, 698 | "source": [ 699 | "Uma guarda de trânsito é designada para controlar o trâfego nos oito cruzametos da rua central. Ela é instruida a permanecer em cada cruzamento por uma hora e, em seguida, ou permanecer no mesmo cruzamento ou seguir para um cruzamento adjacente. Para evitar que ela estabeleça um padrão, ela deve escolher o novo cruzamento de maneira aleatória, com qualquer escolha igualmente provável. Por exemplo, se ela está no cruzamento 5, seu próximo cruzamento pode ser 2, 4, 5 ou 8, cada um com probabilidade de $\\frac{1}{4}$. Cada dia ela começa no cruzamento em que parou no dia anterior. A matriz de transição desta cadeia de Markov é" 700 | ] 701 | }, 702 | { 703 | "cell_type": "code", 704 | "execution_count": 30, 705 | "metadata": {}, 706 | "outputs": [], 707 | "source": [ 708 | "# definindo a matriz de transição C\n", 709 | "C = np.array([[1/3, 1/3, 0 , 1/5, 0 , 0 , 0 , 0 ],\n", 710 | " [1/3, 1/3, 0 , 0 , 1/4, 0 , 0 , 0 ],\n", 711 | " [0 , 0 , 1/3, 1/5, 0 , 1/3, 0 , 0 ],\n", 712 | " [1/3, 0 , 1/3, 1/5, 1/4, 0 , 1/4, 0 ],\n", 713 | " [0 , 1/3, 0 , 1/5, 1/4, 0 , 0 , 1/3],\n", 714 | " [0 , 0 , 1/3, 0 , 0 , 1/3, 1/4, 0 ],\n", 715 | " [0 , 0 , 0 , 1/5, 0 , 1/3, 1/4, 1/3],\n", 716 | " [0 , 0 , 0 , 0 , 1/4, 0 , 1/4, 1/3]])" 717 | ] 718 | }, 719 | { 720 | "cell_type": "code", 721 | "execution_count": 31, 722 | "metadata": {}, 723 | "outputs": [ 724 | { 725 | "name": "stdout", 726 | "output_type": "stream", 727 | "text": [ 728 | "A matriz de transição C é: \n", 729 | "\n", 730 | "[[0.33333333 0.33333333 0. 0.2 0. 0.\n", 731 | " 0. 0. ]\n", 732 | " [0.33333333 0.33333333 0. 0. 0.25 0.\n", 733 | " 0. 0. ]\n", 734 | " [0. 0. 0.33333333 0.2 0. 0.33333333\n", 735 | " 0. 0. ]\n", 736 | " [0.33333333 0. 0.33333333 0.2 0.25 0.\n", 737 | " 0.25 0. ]\n", 738 | " [0. 0.33333333 0. 0.2 0.25 0.\n", 739 | " 0. 0.33333333]\n", 740 | " [0. 0. 0.33333333 0. 0. 0.33333333\n", 741 | " 0.25 0. ]\n", 742 | " [0. 0. 0. 0.2 0. 0.33333333\n", 743 | " 0.25 0.33333333]\n", 744 | " [0. 0. 0. 0. 0.25 0.\n", 745 | " 0.25 0.33333333]]\n" 746 | ] 747 | } 748 | ], 749 | "source": [ 750 | "# imprimindo a matric C\n", 751 | "print(\"A matriz de transição C é: \\n\\n{}\".format(C))" 752 | ] 753 | }, 754 | { 755 | "cell_type": "markdown", 756 | "metadata": {}, 757 | "source": [ 758 | "Temos que a probabilidade da guarda, que está localizada no cruzamento velho **j**, querer ir para o cruzamento **i**, está dada na matriz acima." 759 | ] 760 | }, 761 | { 762 | "cell_type": "markdown", 763 | "metadata": {}, 764 | "source": [ 765 | "Se a guarda inicialmente começa no cruzamento 5, suas prováveis localizações, hora a hora, são dadas pelos vetores abaixo:" 766 | ] 767 | }, 768 | { 769 | "cell_type": "code", 770 | "execution_count": 32, 771 | "metadata": {}, 772 | "outputs": [], 773 | "source": [ 774 | "# determinando o vetor-estado inicial y se ela começar no cruzamento 5\n", 775 | "y = np.array([[0],\n", 776 | " [0],\n", 777 | " [0],\n", 778 | " [0],\n", 779 | " [1],\n", 780 | " [0],\n", 781 | " [0],\n", 782 | " [0]])" 783 | ] 784 | }, 785 | { 786 | "cell_type": "code", 787 | "execution_count": 33, 788 | "metadata": {}, 789 | "outputs": [ 790 | { 791 | "name": "stdout", 792 | "output_type": "stream", 793 | "text": [ 794 | "O vetor-estado y é: \n", 795 | "\n", 796 | "[[0]\n", 797 | " [0]\n", 798 | " [0]\n", 799 | " [0]\n", 800 | " [1]\n", 801 | " [0]\n", 802 | " [0]\n", 803 | " [0]]\n" 804 | ] 805 | } 806 | ], 807 | "source": [ 808 | "# imprimindo o vetor-estado y\n", 809 | "print(\"O vetor-estado y é: \\n\\n{}\".format(y))" 810 | ] 811 | }, 812 | { 813 | "cell_type": "code", 814 | "execution_count": 34, 815 | "metadata": {}, 816 | "outputs": [ 817 | { 818 | "name": "stdout", 819 | "output_type": "stream", 820 | "text": [ 821 | "O vetor-estado na 1º observação é: \n", 822 | "\n", 823 | "[[0. ]\n", 824 | " [0.25]\n", 825 | " [0. ]\n", 826 | " [0.25]\n", 827 | " [0.25]\n", 828 | " [0. ]\n", 829 | " [0. ]\n", 830 | " [0.25]]\n" 831 | ] 832 | } 833 | ], 834 | "source": [ 835 | "# vetor-estado após a 1º observação\n", 836 | "print(\"O vetor-estado na 1º observação é: \\n\\n{}\".format(estado(C, y, transicao = 1)))" 837 | ] 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "metadata": {}, 842 | "source": [ 843 | "Assim, no 1º, 3º, 6º e 7º estados há 0% de chance da guarda ir para o cruzamento novo 1, 3, 6 e 7, respectivamente,e 25% nos 2º, 4º, 5º e 8º estados de chance da guarda mudar para o cruzamento 2, 4, 5 e 8, respectivamente." 844 | ] 845 | }, 846 | { 847 | "cell_type": "code", 848 | "execution_count": 37, 849 | "metadata": {}, 850 | "outputs": [ 851 | { 852 | "name": "stdout", 853 | "output_type": "stream", 854 | "text": [ 855 | "O vetor-estado na 10º observação é: \n", 856 | "\n", 857 | "[[0.11289968]\n", 858 | " [0.11487928]\n", 859 | " [0.10035458]\n", 860 | " [0.17818898]\n", 861 | " [0.1486313 ]\n", 862 | " [0.09887482]\n", 863 | " [0.13813863]\n", 864 | " [0.10803273]]\n" 865 | ] 866 | } 867 | ], 868 | "source": [ 869 | "# vetor-estado após a 10º observação\n", 870 | "print(\"O vetor-estado na 10º observação é: \\n\\n{}\".format(estado(C, y, transicao = 10)))" 871 | ] 872 | }, 873 | { 874 | "cell_type": "code", 875 | "execution_count": 38, 876 | "metadata": {}, 877 | "outputs": [ 878 | { 879 | "name": "stdout", 880 | "output_type": "stream", 881 | "text": [ 882 | "O vetor-estado na 22º observação é: \n", 883 | "\n", 884 | "[[0.10736939]\n", 885 | " [0.1074327 ]\n", 886 | " [0.10691423]\n", 887 | " [0.17857082]\n", 888 | " [0.14304836]\n", 889 | " [0.1068521 ]\n", 890 | " [0.14266778]\n", 891 | " [0.10714462]]\n" 892 | ] 893 | } 894 | ], 895 | "source": [ 896 | "# vetor-estado após a 22º observação\n", 897 | "print(\"O vetor-estado na 22º observação é: \\n\\n{}\".format(estado(C, y, transicao = 22)))" 898 | ] 899 | }, 900 | { 901 | "cell_type": "markdown", 902 | "metadata": {}, 903 | "source": [ 904 | "Para todos valores de n maiores do que 22, todos os vetores-estado são iguais a $x^{(22)}$ até três casas decimais. Assim, como nos dois exemplos anteriores, os vetores-estado convergem a um vetor fixo à medida que n cresce." 905 | ] 906 | }, 907 | { 908 | "cell_type": "markdown", 909 | "metadata": {}, 910 | "source": [ 911 | "### Alguma Dúvida? Entre em Contato Comigo:" 912 | ] 913 | }, 914 | { 915 | "cell_type": "markdown", 916 | "metadata": {}, 917 | "source": [ 918 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);" 919 | ] 920 | } 921 | ], 922 | "metadata": { 923 | "kernelspec": { 924 | "display_name": "Python 3", 925 | "language": "python", 926 | "name": "python3" 927 | }, 928 | "language_info": { 929 | "codemirror_mode": { 930 | "name": "ipython", 931 | "version": 3 932 | }, 933 | "file_extension": ".py", 934 | "mimetype": "text/x-python", 935 | "name": "python", 936 | "nbconvert_exporter": "python", 937 | "pygments_lexer": "ipython3", 938 | "version": "3.7.4" 939 | } 940 | }, 941 | "nbformat": 4, 942 | "nbformat_minor": 4 943 | } 944 | -------------------------------------------------------------------------------- /Conteúdo T - Google Page Rank/prog20_GooglePageRank.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Google PageRank\n", 8 | "#### Atualmente, a pesquisa na Web usa uma variedade de tecnologias, mas o algoritmo original que levou o Google ao topo dos mecanismos de pesquisa é o algoritmo PageRank. Vamos analisar como é a ideia desse algoritmo." 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "O PageRank funciona contando o número e a qualidade dos links de uma página para determinar uma estimativa aproximada da importância do site. A suposição subjacente é que os sites mais importantes provavelmente receberão mais links de outros sites." 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "Dentro de sites há inúmeros **hiperlinks** cuja função é nos direcionar para outros sites. Se formos considerar todas as páginas que temos acesso através do mecanismo de pesquisa do Google, temos um emaranhado de ligações entre sites através de **hiperlinks**. Dizemos que um determinado site **A** aponta para um site **B** quando o site **A** possui pelo menos um **hiperlink** que nos direciona a página **B**." 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "Veja o exemplo abaixo, esse que vamos desenvolver ao longo do progama:" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "|**Relação de hiperlinks entre quatro sites:** |\n", 37 | "|---------------------------------------------------------|\n", 38 | "|A página **A** aponta para a página **B**, **C** e **D**;|\n", 39 | "|A página **B** aponta para a página **C** e **D**; |\n", 40 | "|A página **C** não aponta para niguém; |\n", 41 | "|A página **D** aponta para a página **A** e **C**; |" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "Só de analisar o quadro acima, vemos que a página com mais classificação é a página **C**, pois ela possui mais **Links de Entrada**." 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "> **Links de Entrada:** são links para o site fornecido de fora para outras páginas." 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "> **Links de Saída:** são links de uma determinada página para páginas no mesmo site ou em outro sites." 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "#### Fórmula Original" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "Inicialmente, tinhamos a fórmula recursiva para determinar qual página era mais popular:" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "$$PR(A) = (1 - d) + d( \\frac{PR(T_{1})}{C(T_{1})} + \\frac{PR(T_{2})}{C(T_{2})} + ... + \\frac{PR(T_{n})}{C(T_{n})} )$$" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "- **PR(A)** = **PageRank** da página **A**;\n", 91 | "- **PR($T_{i}$)** = **PageRank** das páginas $T_{i}$ que apontam para a página **A**;\n", 92 | "- **C($T_{i}$)** = Número de **Links de Saída** de uma determinada página $T_{i}$;\n", 93 | "- **d** = também conhecido como **Fator de Amortecimento**, é um número arbitrário entre 0 e 1;" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "No início da fórmula, todas as páginas recebem o mesmo número $\\frac{1}{n}$, esse que vamos chamar de **PageRank** e **n** é o número total de páginas disponíveis naquele espaço amostral da pesquisa. Desse modo, no início do algoritmo, todas as páginas terão o mesmo nível de popularidade. Conseguintemente, teremos que realizar diversas interações até chegar na convergência do resultado, essa que indicará um ranking de páginas populares entre as demais." 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "A fórmula acima pode ser simplificada da seguinte forma:" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "$$PR_{t + 1}(P_{i}) = \\sum_{P_{j}}\\frac{PR_{t}(P_{j})}{C(T_{j})}$$" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "O **Grau de Importância** de uma página da web é calculado a partir do número de **Links de Entrada** nesse site e da importância das páginas que estão apontando para ele. A regra é que uma página com links para $n$ outras páginas passe para eles $\\frac{1}{n}$ de sua importância. O ranking de uma página é a soma de todas as importâncias que recebe de outras páginas vinculadas a ele." 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "#### Exemplo:" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "Vamos aplicar a fórmula anterior e utilizar o mesmo exemplo de sites que estamos trabalhando desde o início." 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "|Sites|0 interação|1 interação|2 interações|PageRank|\n", 143 | "|-----|-----------|-----------|------------|--------|\n", 144 | "|A|$\\frac{1}{4}$|$\\frac{\\frac{1}{4}}{2}$ = $\\frac{1}{8}$|$\\frac{\\frac{1}{8}}{2}$ = $\\frac{1}{16}$|0.0625|\n", 145 | "|B|$\\frac{1}{4}$|$\\frac{\\frac{1}{4}}{3}$ = $\\frac{1}{12}$|$\\frac{\\frac{1}{8}}{3}$ = $\\frac{1}{24}$|0.0416|\n", 146 | "|C|$\\frac{1}{4}$|$\\frac{\\frac{1}{4}}{3}$ + $\\frac{\\frac{1}{4}}{2}$ + $\\frac{\\frac{1}{4}}{2}$ = $\\frac{1}{3}$|$\\frac{\\frac{1}{8}}{3}$ + $\\frac{\\frac{1}{12}}{2}$ + $\\frac{\\frac{1}{8}}{2}$ = $\\frac{7}{48}$|0.1458|\n", 147 | "|D|$\\frac{1}{4}$|$\\frac{\\frac{1}{4}}{2} = \\frac{1}{8}$|$\\frac{\\frac{1}{12}}{2}$ = $\\frac{1}{24}$|0.0416|" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": {}, 153 | "source": [ 154 | "Veja que todas as páginas no início receberam o mesmo **PageRank** de $\\frac{1}{4}$. Na próxima interação, consideramos a soma dos **PageRank** de todos sites que apontam para o site **n** dividido pelo número de **Links de Saída** dos mesmos, e assim sucessivamente para cada interação." 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "Desse modo, pode-se perceber que a página mais influente é de fato a página **C**. Em segundo lugar, temos a página **A** e empatados em terceiro lugar temos as páginas **B** e **D**. Caso fosse um ranking de páginas sobre algum assunto que você pesquisou no Google, certamente a pagina **C** lideraria o topo de sua pesquisa, pois ela é a mais influente neste **Networking**." 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "Mas perceba que o resultado não foi justo. A página **C** realmente é a mais influente de todas, porém a página **D** é mais influente que a página **A**, dado que **D** possui 2 **Links de Saída** e também 2 **Links de Entrada**, ao passo em que a página **A** possui 3 **Links de Saída** e apenas 1 **Link de Entrada**. Assim, teremos que aprimorar nosso algoritmo, mas para isso, necessitamos desenvolver algumas ideias antes." 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": {}, 174 | "source": [ 175 | "#### Curiosidade" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": {}, 181 | "source": [ 182 | "| |\n", 183 | "|--|\n", 184 | "|Certamente todos nós conhecemos a empresa **Wikipédia**. A sua popularidade advém da inteligência dos desenvolvedores originais em usar o **PageRank** ao seu favor. Ao clicar em uma página qualquer da Wikipédia, podemos encontrar inúmeros **Links de Saída** para outras páginas da mesma empresa e, obviamente, essa mesma página possui muitos **Links de Entrada** apontando para ele. Desse modo, quando nós utilizamos o mecanismo de pesquisa do Google para procurar algum assunto, a Wikipédia certamente estará em primeiro lugar nos sites recomendados para tal assunto, se o mesmo estiver catalogado no site. Além disso, tal algoritmo foi inspiração para inúmeras outras plataformas. Um exemplo maior dessa inspiração é o aplicativo de fotos **Instagram** e o aplicativo de vídeos **YouTube** que, além de usar inúmeras tecnologias de recomendação, usa também um recurso chamado **tags**.|" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": {}, 190 | "source": [ 191 | "> **Tags:** Uma tag, ou em português etiqueta, é uma palavra-chave ou termo associado com uma informação que o descreve e permite uma classificação da informação baseada em palavras-chave. " 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": {}, 197 | "source": [ 198 | "#### Usando Matrizes no Algoritmo PageRank" 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "metadata": {}, 204 | "source": [ 205 | "podemos usar operações matriciais ao invés do **Algoritmo Iterativo** acima. Desse modo, podemos fazer diversas operações ao mesmo tempo, fato esse mais viável para o mecanismo de pesquisa do Google, dado que em uma única pesquisa temos milhares de páginas que competem a atenção do usuário." 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "metadata": {}, 211 | "source": [ 212 | "Para uma rede de páginas da web **n**, você forma uma matriz cuja entrada **i** e **j** é a página de importância que **j** passa para **i**. Vamos usar o mesmo exemplo acima é montar sua **Matriz de Transição**." 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "|**Organização de Links das Páginas** |\n", 220 | "|-------------------------------------------------------------------------------------------------|\n", 221 | "|A página **A** possui 3 links: passa $\\frac{1}{3}$ de sua classificação para **B**, **C**, **D**;|\n", 222 | "|A página **B** possui 2 links: passa $\\frac{1}{2}$ de sua classificação para **C** e **D**; |\n", 223 | "|A página **C** possui 0 links; |\n", 224 | "|A página **D** possui 2 links: passa $\\frac{1}{2}$ de sua classificação para **A** e **C**; |" 225 | ] 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "metadata": {}, 230 | "source": [ 231 | "|**Matriz de Transição**|**A** |**B** |**C**|**D** |\n", 232 | "|-----------------------|-----------------|-----------------|-----|-----------------|\n", 233 | "|**A** |0 |0 |0 |$\\frac{1}{2}$ |\n", 234 | "|**B** |$\\frac{1}{3}$ |0 |0 |0 |\n", 235 | "|**C** |$\\frac{1}{3}$ |$\\frac{1}{2}$ |0 |$\\frac{1}{2}$ |\n", 236 | "|**D** |$\\frac{1}{3}$ |$\\frac{1}{2}$ |0 |0 |" 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": {}, 242 | "source": [ 243 | "Essa seria uma **Matriz de Transição**, exceto pela coluna de zeros, devido a uma página da Web sem links. Esse problema é facilmente corrijido substituindo os zeros nessa coluna por $\\frac{1}{n}$. Além disso, deve-se escolher um valor para o **Fator de Amortecimento (d)**." 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "Temos uma versão da fórmula anterior, apropiada para o uso de matrizes:\n" 251 | ] 252 | }, 253 | { 254 | "cell_type": "markdown", 255 | "metadata": {}, 256 | "source": [ 257 | "$$M = (1-d)A + dB$$" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": {}, 263 | "source": [ 264 | "Temos que:\n", 265 | "- **M** é a chamada **Matriz PageRank** ou **Google-Matrix**;\n", 266 | "- **d**: é chamado **Fator de Amortecimento**, um número entre 0 e 1 (vamos usar o valor 0.15);\n", 267 | "- **A**: é a chamada **Matriz de Transição**;\n", 268 | "- **B**: é uma matriz com todos elementos compostos pelo valor $\\frac{1}{n}$;" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "Veja que o **Fator de Amortecimento** **d** é usado duas vezes na fórmula. O primeiro uso associado a **Matriz de Transição** **A** indica a probabilidade do usuário ir para uma outra página através dos **Links de Saída** da mesma. O segundo uso associado a matriz **B** é a probabilidade do usuário ir para outra página sobre o tema, mas sem usar os seus **Links de Saída**, fator esse chamado de **Teletransporte**. Por tal motivo, **A** é a matriz dos **Links de Saída e Entrada**, também chamada de **Matriz de Transição**, e a matriz **B** possui todos os elementos com $\\frac{1}{n}$ para todas as páginas disponíveis naquele **Networking**, com o mesmo valor de **PageRank** para qualquer página." 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "metadata": {}, 281 | "source": [ 282 | "#### Cadeias de Markov e Teorema de Perron-Frobenius" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": {}, 288 | "source": [ 289 | "Vamos usar nesse algoritmo ideias de **cadeias de Markov** em que uma determinada **Matriz de Transição**, após passar por cada operação, vai sofrer uma **Mudança de Estado**. (Veja o progama sobre Cadeias de Markov disponível no repositório)." 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "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 fazer é 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:" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "$$x = \\begin{bmatrix}\n", 304 | " x_{1} \\\\\n", 305 | " x_{2} \\\\\n", 306 | " x_{3} \\\\\n", 307 | " \\end{bmatrix}$$" 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "metadata": {}, 313 | "source": [ 314 | "no 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:" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "> 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." 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "O **Teorema de Perron-Frobenius** afirma que:" 329 | ] 330 | }, 331 | { 332 | "cell_type": "markdown", 333 | "metadata": {}, 334 | "source": [ 335 | "> Uma matriz real quadrada com entradas positivas tem um único maior autovalor e que o correspondente autovetor tem componentes estritamente positivos." 336 | ] 337 | }, 338 | { 339 | "cell_type": "markdown", 340 | "metadata": {}, 341 | "source": [ 342 | "Além de outras definições que estão além do nosso objetivo no **Teorema de Perron-Frobenius** , temos que o **PageRank** será um vetor-coluna em que 1 será o maior **autovalor** e, para esse **autovalor**, teremos um único **autovetor** cuja soma de todas as entradas é igual a 1 (fato esse compreensível por ser tratar de probabilidade)." 343 | ] 344 | }, 345 | { 346 | "cell_type": "markdown", 347 | "metadata": {}, 348 | "source": [ 349 | "Em outras palavras:" 350 | ] 351 | }, 352 | { 353 | "cell_type": "markdown", 354 | "metadata": {}, 355 | "source": [ 356 | "> \"A Soma de Todas as Páginas rankeadas é igual a 1\" $_{perron-frobenius}$" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": {}, 362 | "source": [ 363 | "Em suma, temos que:" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": {}, 369 | "source": [ 370 | "- **PageRank** pode ser definido pela probabilidade de um usuário na web iniciar uma **página aleatória** ou seguir **hiperlinks** e visitar as páginas fornecida.\n", 371 | "- A soma das colunas deve ser igual a 1 por causa das probabilidades (Teoria de **cadeias de Markov** e **𝑝𝑒𝑟𝑟𝑜𝑛−𝑓𝑟𝑜𝑏𝑒𝑛𝑖𝑢𝑠**);\n", 372 | "- A matriz de transição define os próximos passos até o **PageRank**;" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "#### Teorema da Convergência do Método da Potência" 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": {}, 385 | "source": [ 386 | "Por fim, para obter nosso **PageRank**, vamos utilizar todas as ideias desenvolvidas acima para usar o **Teorema da Convergência do Método da Potência**, que nos diz o seguinte:" 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": {}, 392 | "source": [ 393 | "A partir da matriz **M**: matriz positiva e com colunas estocásticas, nós teremos um vetor-coluna **w** que é o **autovetor** correspondente ao **autovalor** 1; temos **v**, o vetor inicial com todas as entradas iguais a $\\frac{1}{n}$, responsável por indicar que os sites tem igual probabilidade de influência antes da **Distribuição Estacionária**. Nesse caso, a sequência $v, Mv, ..., M^{k}v$ converge para o vetor **w** (**Teorema da Convergência do Método da Potência**)." 394 | ] 395 | }, 396 | { 397 | "cell_type": "markdown", 398 | "metadata": {}, 399 | "source": [ 400 | "Agora vamos desenvolver o **Algoritmo PageRank** usando o exemplo de sites acima." 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": 8, 406 | "metadata": {}, 407 | "outputs": [], 408 | "source": [ 409 | "# importando a biblioteca de funções numpy do Python\n", 410 | "import numpy as np" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 9, 416 | "metadata": {}, 417 | "outputs": [], 418 | "source": [ 419 | "# definindo a matriz de transição A\n", 420 | "A = np.array([[0,0,1/4, 1/2], [1/3,0,1/4,0], [1/3,1/2,1/4,1/2],[1/3,1/2,1/4,0]])" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 10, 426 | "metadata": {}, 427 | "outputs": [ 428 | { 429 | "name": "stdout", 430 | "output_type": "stream", 431 | "text": [ 432 | "A Matriz de Transição A é:\n", 433 | "\n", 434 | "[[0. 0. 0.25 0.5 ]\n", 435 | " [0.33333333 0. 0.25 0. ]\n", 436 | " [0.33333333 0.5 0.25 0.5 ]\n", 437 | " [0.33333333 0.5 0.25 0. ]]\n" 438 | ] 439 | } 440 | ], 441 | "source": [ 442 | "# imprimindo a matriz A\n", 443 | "print(\"A Matriz de Transição A é:\\n\\n{}\".format(A))" 444 | ] 445 | }, 446 | { 447 | "cell_type": "markdown", 448 | "metadata": {}, 449 | "source": [ 450 | "Vamos escrever uma função Python com o algoritmo PageRank, tendo como entradas a **Matriz de Transição** **A** e o **Fator de Amortecimento** **d**." 451 | ] 452 | }, 453 | { 454 | "cell_type": "code", 455 | "execution_count": 11, 456 | "metadata": {}, 457 | "outputs": [], 458 | "source": [ 459 | "# vamos definir a função pagerank\n", 460 | "def pagerank(A, d = 0.15):\n", 461 | " \n", 462 | " # n recebe o total de linhas da matriz de transição A, correspondendo ao número de sites\n", 463 | " n = A.shape[0]\n", 464 | " \n", 465 | " # inicializa o vetor v, com igual probabilidade para todos os sites antes da distribuição estacionária\n", 466 | " v = np.array([[1/n],[1/n],[1/n],[1/n]])\n", 467 | " \n", 468 | " # calcula G da fórmula acima\n", 469 | " M = (1 - d) * A + d * (1/n) * np.ones((n,n))\n", 470 | " \n", 471 | " # a matriz vAux é um vetor coluna de n linhas, assim como n foi definido acima\n", 472 | " # ela é apenas uma matriz auxiliar para v\n", 473 | " vAux = np.zeros((n,1))\n", 474 | " \n", 475 | " # estrutura de repetição while \n", 476 | " for indice in range (0,2):\n", 477 | " # vAux recebe uma cópia de v em cada mudança de estado\n", 478 | " vAux = v.copy()\n", 479 | " # realiza a multiplicação da Matriz PageRank M com o vetor-estado v\n", 480 | " v = M.dot(v)\n", 481 | " \n", 482 | " # retorna o vetor v normalizado\n", 483 | " return v/np.sum(v)" 484 | ] 485 | }, 486 | { 487 | "cell_type": "code", 488 | "execution_count": 12, 489 | "metadata": {}, 490 | "outputs": [ 491 | { 492 | "name": "stdout", 493 | "output_type": "stream", 494 | "text": [ 495 | "[[0.23074219]\n", 496 | " [0.1727474 ]\n", 497 | " [0.35514323]\n", 498 | " [0.24136719]]\n" 499 | ] 500 | } 501 | ], 502 | "source": [ 503 | "print(pagerank(A))" 504 | ] 505 | }, 506 | { 507 | "cell_type": "markdown", 508 | "metadata": {}, 509 | "source": [ 510 | "Finalmente, temos um resultado justo para as páginas. Segundo esse algoritmo, temos o seguinte ranking das páginas:" 511 | ] 512 | }, 513 | { 514 | "cell_type": "markdown", 515 | "metadata": {}, 516 | "source": [ 517 | "|**Rank**|**Página** |\n", 518 | "|--------|------------|\n", 519 | "|**1º** |Página **C**|\n", 520 | "|**2º** |Página **D**|\n", 521 | "|**3º** |Página **A**|\n", 522 | "|**4º** |Página **B**|" 523 | ] 524 | }, 525 | { 526 | "cell_type": "markdown", 527 | "metadata": {}, 528 | "source": [ 529 | "### O que a Inteligência Artificial tem Haver com Isso?" 530 | ] 531 | }, 532 | { 533 | "cell_type": "markdown", 534 | "metadata": {}, 535 | "source": [ 536 | "Praticamente mihões de pessoas utilizam sistemas de streaming para o seu entretenimento. Nesses serviços, geralmente existem um sistema complexo de recomendação de conteúdos com base no gosto do usuário, fazendo com que conteúdos aparecem personalizados para o cliente, mais próximos da sua personalidade. Os algoritmos que estão por trás dessa ideia são algoritmos de Machine Learning que fazem classificação. Por exemplo, a partir de um filme A assistido, é recomendado um filme B, esse que possui semelhanças com o filme A. Um dos algoritmos de Machine Learning que tem esse poder é chamado de KNN, ele calcula os chamados 'vizinhos próximos' de um dado através de fórmulas de distância, coma distância média quadrática (também conhecida como distância euclidiana). Vale a pena estudar sobre isso!" 537 | ] 538 | }, 539 | { 540 | "cell_type": "markdown", 541 | "metadata": {}, 542 | "source": [ 543 | "#### Referências" 544 | ] 545 | }, 546 | { 547 | "cell_type": "markdown", 548 | "metadata": {}, 549 | "source": [ 550 | "- Page, Lawrence; Brin, Sergey; Motwani, Rajeev and Winograd, Terry (1998), The PageRank Citation Ranking: Bringing Order to the Web, Relatório Técnico, Stanford University. Disponível em: . Acesso em: 10, Fevereiro 2020.\n", 551 | "- Álgebra Linear com aplicações / Anton Howard e Chris Rorres; trad. Claus Ivo Doering. - 8. ed. - Porto Alegre: Bookman, 2001.\n", 552 | "- Leon, Steven J., 1943 - Álgebra Linear com Aplicações/ Steven J. Leon; tradução Valéria de Magalhães Iório - [reimpr]. Rio de Janeiro: LTC, 2008.\n", 553 | "- PageRank (Google) Algorithm Explained. Global Software Support, 26, Setembro 2019. Disponível em: . Acesso em: 10, Fevereiro 2020." 554 | ] 555 | }, 556 | { 557 | "cell_type": "markdown", 558 | "metadata": {}, 559 | "source": [ 560 | "### Alguma Dúvida? Entre em Contato Comigo:" 561 | ] 562 | }, 563 | { 564 | "cell_type": "markdown", 565 | "metadata": {}, 566 | "source": [ 567 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);" 568 | ] 569 | } 570 | ], 571 | "metadata": { 572 | "kernelspec": { 573 | "display_name": "Python 3", 574 | "language": "python", 575 | "name": "python3" 576 | }, 577 | "language_info": { 578 | "codemirror_mode": { 579 | "name": "ipython", 580 | "version": 3 581 | }, 582 | "file_extension": ".py", 583 | "mimetype": "text/x-python", 584 | "name": "python", 585 | "nbconvert_exporter": "python", 586 | "pygments_lexer": "ipython3", 587 | "version": "3.7.4" 588 | } 589 | }, 590 | "nbformat": 4, 591 | "nbformat_minor": 4 592 | } 593 | -------------------------------------------------------------------------------- /Conteúdo V - Processamento de Imagens Digitais/melhorramodomundo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alyssonmach/Algebra-Linear-com-Python/a48b1eddf6f13cd87af043f3be7bb7966ce56a54/Conteúdo V - Processamento de Imagens Digitais/melhorramodomundo.jpg -------------------------------------------------------------------------------- /Conteúdo W - Verifique a Instalação/VerifiqueInstalacao.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Verifique se Todas as Bibliotecas Necessárias Foram Importadas\n", 8 | "#### O progama abaixo tem a finalidade complementar e opcional para verificar se todas as bibliotecas que serão utilizadas nesse repositório estão instaladas caso você tenha optado por instalar todo o ambiente de trabalhado Python em sua máquina." 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "Se estiver faltando alguma, o método mais comum após instalar o Python em sua máquina é o seguinte:" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "Abra o prompt de comando da sua máquina e digite:" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "- **pip install numpy**\n", 30 | "- **pip install matplotlib**\n", 31 | "- **_pip install jupyter_** ou **pip install jupyter lab**\n", 32 | "- **_pip install sympy_**\n", 33 | "- **_pip install imageio_**\n", 34 | "- **_pip install ipywidgets_**\n", 35 | "- **_pip install scipy_**" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "> Lembrando que tal método pode ser realizado no sistema operacional Linux, Windows ou macOS." 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 1, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "numpy ... OK\n", 55 | "matplotlib ... OK\n", 56 | "jupyter ... OK\n", 57 | "sympy ... OK\n", 58 | "imageio ... OK\n", 59 | "ipywidgets ... OK\n", 60 | "scipy ... OK\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "import importlib\n", 66 | "from sys import version_info\n", 67 | "from distutils.version import StrictVersion\n", 68 | "\n", 69 | "def compare_version(module, version):\n", 70 | " version_loaded = importlib.import_module(module).__version__\n", 71 | " if StrictVersion(version_loaded) < StrictVersion(version):\n", 72 | " return 'Versão Atual {}, use \"pip install\" eatualize para {} ou mais tarde'.format(version_loaded, version)\n", 73 | " return None\n", 74 | "\n", 75 | "def main():\n", 76 | " try:\n", 77 | " assert version_info >= (3,5)\n", 78 | " except AssertionError:\n", 79 | " print('Precisa-se da versão 3.5 do Python ou mais atualizada')\n", 80 | "\n", 81 | " modules = {'numpy': '1.15.1',\n", 82 | " 'matplotlib': '2.0.2',\n", 83 | " 'jupyter': None,\n", 84 | " 'sympy': None,\n", 85 | " 'imageio': None,\n", 86 | " 'ipywidgets': None,\n", 87 | " 'scipy': None}\n", 88 | "\n", 89 | " for module, version in modules.items():\n", 90 | " spec = importlib.util.find_spec(module)\n", 91 | " if spec is None:\n", 92 | " print('{} ... não foi encontrado, use o \"pip install\"'.format(module))\n", 93 | " else:\n", 94 | " if version is not None:\n", 95 | " msg = compare_version(module, version)\n", 96 | " if msg is not None:\n", 97 | " print('{} ... {}'.format(module, msg))\n", 98 | " else:\n", 99 | " print('{} ... OK'.format(module))\n", 100 | " else:\n", 101 | " print('{} ... OK'.format(module))\n", 102 | "\n", 103 | "if __name__ == '__main__':\n", 104 | " main()" 105 | ] 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "Caso esteja tudo instalado, o progama compilará como o exemplo acima." 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "### Alguma Dúvida? Entre em Contato Comigo:" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "- [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br);" 126 | ] 127 | } 128 | ], 129 | "metadata": { 130 | "kernelspec": { 131 | "display_name": "Python 3", 132 | "language": "python", 133 | "name": "python3" 134 | }, 135 | "language_info": { 136 | "codemirror_mode": { 137 | "name": "ipython", 138 | "version": 3 139 | }, 140 | "file_extension": ".py", 141 | "mimetype": "text/x-python", 142 | "name": "python", 143 | "nbconvert_exporter": "python", 144 | "pygments_lexer": "ipython3", 145 | "version": "3.7.4" 146 | } 147 | }, 148 | "nbformat": 4, 149 | "nbformat_minor": 4 150 | } 151 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alysson Machado 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Álgebra Linear com Python 2 | #### Aplicações dos tópicos aprendidos na disciplina Álgebra Linear usando a linguagem de programação Python. 3 | 4 | - [Visite o Site](https://algebralinearufcg.github.io) 5 | 6 | ![apresentacao-algebra-linear-python](https://user-images.githubusercontent.com/58775072/86921345-5eedeb00-c101-11ea-863c-b8bd4bb2855a.png) 7 | 8 | ### Conteúdos do Repositório 9 | 10 | |**Conteúdo**|**Tópicos**| 11 | |:-----------|:----------| 12 | |**Conteúdo A**|[Aprendendo Python](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20A%20-%20Aprendendo%20Python)| 13 | |**Conteúdo B**|[Aprendendo Numpy](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20B%20-%20Aprendendo%20Numpy)| 14 | |**Conteúdo C**|[Aprendendo Matplotlib](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20C%20-%20Aprendendo%20Matplotlib)| 15 | |**Conteúdo D**|[Operações Matriciais](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20D%20-%20Opera%C3%A7%C3%B5es%20Matriciais)| 16 | |**Conteúdo E**|[Aplicação de Matrizes](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20E%20-%20Aplica%C3%A7%C3%A3o%20de%20Matrizes)| 17 | |**Conteúdo F**|[Matriz Transposta](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20F%20-%20Matriz%20Transposta)| 18 | |**Conteúdo G**|[Matriz Inversa](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20G%20-%20Matriz%20Inversa)| 19 | |**Conteúdo H**|[Determinante](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20H%20-%20Determinante)| 20 | |**Conteúdo I**|[Sistemas Lineares](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20I%20-%20Sistemas%20Lineares)| 21 | |**Conteúdo J**|[Transformações Lineares]()| 22 | |**Conteúdo K**|[Estudo de Sistemas de Equações](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20K%20-%20Estudo%20de%20Sistemas%20de%20Equa%C3%A7%C3%B5es)| 23 | |**Conteúdo L**|[Autovalores e Autovetores](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20L%20-%20Autovalores%20e%20Autovetores)| 24 | |**Conteúdo M**|[Autovalores em Ecologia](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20M%20-%20Autovalores%20em%20Ecologia)| 25 | |**Conteúdo N**|[Transformando um Círculo em uma Elípse](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20N%20-%20Transformando%20um%20C%C3%ADrculo%20em%20uma%20El%C3%ADpse)| 26 | |**Conteúdo O**|[A Geometria das Transformações Lineares](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20O%20-%20A%20Geometria%20das%20Transforma%C3%A7%C3%B5es%20Lineares)| 27 | |**Conteúdo P**|[Contrução de Curvas por Pontos Especificados](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20P%20-%20Constru%C3%A7%C3%A3o%20de%20Curvas%20por%20Pontos%20Especificados)| 28 | |**Conteúdo Q**|[Criptografia](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20Q%20-%20Criptografia)| 29 | |**Conteúdo R**|[Teoria dos Grafos](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20R%20-%20Teoria%20dos%20Grafos)| 30 | |**Conteúdo S**|[Cadeias de Markov](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20S%20-%20Cadeias%20de%20Markov)| 31 | |**Conteúdo T**|[Google Page Rank](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20T%20-%20Google%20Page%20Rank)| 32 | |**Conteúdo U**|[Problemas de Mínimos Quadráticos](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20U%20-%20Problemas%20de%20M%C3%ADnimos%20Quadr%C3%A1ticos)| 33 | |**Conteúdo V**|[Processamento de Imagens Digitais](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20V%20-%20Processamento%20de%20Imagens%20Digitais)| 34 | |**Conteúdo W**|[Verifique a Instalação](https://github.com/Alyssonmach/Algebra-Linear-com-Python/tree/master/Conte%C3%BAdo%20W%20-%20Verifique%20a%20Instala%C3%A7%C3%A3o)| 35 | 36 | ### Começando 37 | Essas instruções tem a finalidade de mostrar-lhes como baixar e usar os códigos do repositório em suas máquinas, visando compilar e 38 | editar para diversas finalidades. 39 | 40 | ### Pré-requisitos 41 | É interessante que o usuário tenho instalado todo o ambiente de trabalho Python em sua máquina. Caso não seja viável a instalação, não se preocupe. Há outras formas pela qual é possível acessar os progamas do repositório. Vamos apresentar o Google Colab Notebook mais adiante e, através dele, você aprenderá como é possível usá-lo para baixar os progamas e executá-los através do seu navegador Google Chrome. 42 | 43 | ### Instalando 44 | 45 | #### Baixando o ambiente de trabalho Python em sua máquina. 46 | 47 | Veja o vídeo abaixo para instalar devidamente o Python em sua máquina (disponível para Windows, Linux e MacOS). 48 | 49 | - [Instalando o Python3](https://www.youtube.com/watch?v=VuKvR1J2LQE) 50 | 51 | Após todos os procedimentos do vídeo terem sido realizados, abra o prompt de comando da sua máquina e digite os seguintes comandos 52 | para importar todas as bibliotecas usadas nos progamas do repositório: 53 | 54 | 1. **_pip install numpy_** 55 | 2. **_pip install matplotlib_** 56 | 3. **_pip install scipy_** 57 | 4. **_pip install jupyter_** ou **_pip install jupyter lab_** 58 | 5. **_pip install sympy_** 59 | 6. **_pip install imageio_** 60 | 7. **_pip install ipywidgets_** 61 | 62 | Após importar todas as bibliotecas acima você terá todos os requisitos necessários para compilar os progamas apresentados no repositório. 63 | Verifique no progama abaixo se todos as bibliotecas foram devidamente importadas: 64 | 65 | - [Verifique a Instalação](https://github.com/Alyssonmach/Algebra-Linear-com-Python/blob/master/Conte%C3%BAdo%20W%20-%20Verifique%20a%20Instala%C3%A7%C3%A3o/VerifiqueInstalacao.ipynb) 66 | 67 | #### Usando o Google Colab Notebook 68 | 69 | Como foi dito acima, outra opção razoável é usar o Google Colab Notebook. Vale salientar que por mais completo que seja essa instrumento 70 | de trabalho da Google, ele não possuí todas as bibliotecas disponíveis acima. Entretanto, você pode verificar qual célula não compilará. 71 | Um dos erros possíveis é a não disponibilidade de algumas no servidor. Para contornar tal fato, crie uma nova célula de código(CODE) 72 | e digite **_pip install []_**, na qual [] será o nome da biblioteca a ser importada. Veja o vídeo abaixo para ter uma ideia de como 73 | utilizar o Google Colab Notebook. 74 | 75 | - [Get started with Google Colaboratory](https://www.youtube.com/watch?v=inN8seMm7UI) 76 | 77 | ### Compilando 78 | 79 | Vamos agora aprender a compilar todos os progamas do repositório dado que todos os passos acima estão satisfeitos. O arquivo .ipynb 80 | utilizando é um forte instrumento para se utilizar quando deseja-se estudar tópicos de programação voltados para algum assunto 81 | didático. No nosso repositório, usamos tal instrumento para trazer aplicações da disciplina de Álgebra Linear computacionalmente. 82 | Muito além de ser algo complementar no aprendizado, é também um ótimo começo para quem deseja aprender a linguagem de programação 83 | Python, dado que é uma linguagem com amplas funcionalidades para diversas áreas de trabalho. 84 | 85 | #### Como usar os notebooks 86 | 87 | Os arquivos com extensão .ipynb são chamados de notebooks. Um notebook é composto por células, essas que obedecem as normas vigentes de 88 | boa prática de programação: a ideia da programação sequencial. Uma célula pode ser de dois tipos: célula de código (Code) ou célula de 89 | texto (Markdown). As células de texto são independentes entre si em um viés computacional, pois a execução da mesma não vai 90 | interferir nas células de código. Sobre o viés do aluno, é interessante para o seu entendimento que a leitura das mesmas seja feito 91 | sequencialmente, dado que algumas células desenvolvidas anteriormente ajudam no entendimentos das desenvolvidas posteriormente. As 92 | células de código, como foi dito acima, obedecem a ideia da programação sequencial. Desse modo, é fundamental que: 93 | 94 | > **TODAS AS CÉLULAS DE CÓDIGO DEVEM SER EXECUTADAS, DO INÍCIO AO FIM, DADO QUE AS CÉLULAS POSTERIORES SÃO DEPENDENTES DAS CÉLULAS ANTERIORES** 95 | 96 | Caso contrário, erros de compilação surgirão, interrompendo o funcionamento do progama. 97 | 98 | #### Abrindo um notebook 99 | 100 | Para quem optou por instalar na sua máquina o ambiente de trabalho do Python, pode seguir as seguintes instruções para abrir um 101 | notebook em sua máquina: 102 | 103 | 1. Abra o prompt de comando. 104 | 2. Digite **_jupyter notebook_**, caso tenha optado pelo método de instalação **_pip install jupyter_** ou digite **_jupyter lab_**, 105 | caso tenha optado pela opção de instalação **_pip install jupyter lab_**. 106 | 107 | > **Jupyter Notebook tem o mesmo funcionamento do Jupyter Lab, a única diferença é que o segundo é uma versão do aplicativo mais recente que a primeira.** 108 | 109 | 3. Após ter feito isso, será criado no seu prompt de comando uma espécie de servidor local e o aplicativo será aberto em seu browser 110 | padrão. 111 | 112 | > **NÃO FECHE O SEU PROMPT DE COMANDO ENQUANTO ESTIVER USANDO O JUPYTER NOTEBOOK OU JUPYTER LAB, CASO CONTRÁRIO, O KERNEL DO APLICATIVO SERÁ ENCERRADO JUNTO.** 113 | 114 | 4. Caso você queira criar um novo notebook, clique na opção "New Launcher". Dentro do progama: 115 | - [x] Ícone do disquete("Save the notebook contents and create checkpoint"): salva o seu progama; 116 | - [x] Ícone de +("Insert a cell below"): Insere uma célula no seu notebook; 117 | - [x] Ícone de tesoura("Cut the selected cells"): corta alguma célula selecionada do seu progama; 118 | - [x] Ícone de copiar("Copy the selected cells"): copia uma célula do seu progama; 119 | - [x] Ícone da prancheta("Paste cells from the clipboard"): cola a célula copiada; 120 | - [x] Ícone de dar play("Run the selected cells and advance"): compila a célula selecionada; 121 | - [x] Ícone de parar("Interrupt the Kernel"): Interrompe a compilação da célula em processo; 122 | - [x] Ícone de reiniciar("Restart the Kernel"): Reinicia a compilação da célula em processo; 123 | - [x] Opção Markdown: Transforma a célula selecionada em uma célula de texto; 124 | - [x] Opção Code: Transforma a célula selecionada em uma célula de código; 125 | 5. Caso você queira criar uma pasta, clique na opção "New folder". 126 | 6. Caso você queira adicionar um novo arquivo .ipynb do seu computador, clique na opção "Upload Files". 127 | 128 | Para quem optou usar o Google Colab Notebook, pode seguir as seguintes instruções para executar um notebook em um servidor pelo 129 | Google Browser. 130 | 131 | 1. Logo no início, aparecerá uma janela com diversas opções, nela você pode fazer os seguintes passos: 132 | - [x] Na aba "Examples", temos uma série de progamas .ipynb fornecidos pelo Google para familiarizar o usuário com o aplicativo; 133 | - [x] Na aba "Recent", é possível ver os progamas .ipynb acessados recentemente; 134 | - [x] Na aba "Google Drive", você verá todos os seus progamas criados; 135 | > **Todos os progamas criados no Google Colab Notebook são salvos no Google Drive e vinculado a conta do usuário.** 136 | - [x] Na aba "GitHub", pode-se copiar a URL do repositório que tem uma extensão .ipynb e usá-lo para abrir o progama do GitHub no 137 | Google Colab Notebook de forma direta; 138 | > **PARA USUÁRIOS DO GOOGLE COLAB NOTEBOOK, ESSA SERÁ A FORMA DE ACESSAR OS PROGRAMAS DO NOSSO REPOSITÓRIO** 139 | - [x] Na aba "Upload" você pode adicionar um progama .ipynb do seu computador diretamente no Google Colab Notebook. 140 | 2. Na opção "New Python3 Notebook" você conseguirá criar um novo notebook. Vamos agora aprender os comandos para prosseguir com essa 141 | criação. 142 | - [x] Na opção "+ Code", você pode adicionar uma célula de código; 143 | - [x] Na opção "+ Text", você pode adicionar uma célula de texto; 144 | - [x] Clicando em "file": salva o seu progama; 145 | - [x] Ícone de lixeira: exclui alguma célula selecionada do seu progama; 146 | - [x] Nos três pontos para ter acesso a mais opções na célula, você pode achar a opção "Copy cell", para copiar a célula; 147 | - [x] Ao lado de cada célula, há uma opção para compilar ela, assim, você pode executar as células de código; 148 | - [x] Clicando na opção "runtime", você pode achar a opção "Run all", para compilar todas as células do progama de uma vez só; 149 | 150 | ### Baixando Arquivos do GitHub 151 | 152 | #### Baixar pelo próprio GitHub 153 | 154 | 1. Primeiramente, clique no arquivo que você deseja baixar no GitHub. 155 | 2. Após clicar no arquivo desejado com extensão .ipynb, você conseguirá ver o arquivo, mas não poderá interagir com ele. 156 | 3. Clique na opção Raw e, após isso, clique em "Ctrl + S" para salvar o arquivo em seu computador. 157 | 4. Repare que o tipo do arquivo está como um documento de texto, você deve modificar essa opção para "Todo tipo de arquivo" e modificar também o nome do documento. A extensão .ipynb deve ser mantida. 158 | 5. O nome do documento deve terminar com .ipynb, respeitando as regras ao colocar o nome no arquivo, para que ele compile. 159 | 6. Abra o seu Jupyter Notebook ou Google Colab Notebook. 160 | 7. Faça o upload do arquivo e pronto, você terá um arquivo .ipynb na qual você pode interagir, editar, remover ou adicionar células. 161 | 162 | #### Usando o nbviewer 163 | 164 | O próprio Jupyter Project fornece uma ferramenta para que o usuário consiga baixar e visualizar arquivos .ipynb a partir do GitHub. 165 | Segue o link do site para acessar o nbviewer. 166 | 167 | - [nbviewer](https://nbviewer.jupyter.org/) 168 | 169 | 1. Insira o link do progama disponível do repositório e clique em pesquisar. 170 | 2. Clique em "Download Notebook" para baixar o arquivo na sua máquina. 171 | 172 | ### Usando o binder para compilar os progamas 173 | 174 | Uma opção terciária para executar os progamas .ipynb é usando o binder, do próprio nbviewer. Veja os passos abaixo: 175 | 176 | 1. Insira o link do progama disponível no repositório e clique em pesquisar. 177 | 2. Clique na opção "Execute on Binder". 178 | 3. Abrirá no browser um aplicativo Jupyter Notebook. 179 | 180 | ### Minicurso de Git GitHub 181 | 182 | - [Acesse o site](https://algebralinearufcg.github.io/listadegithub.html) 183 | 184 | ![minicurso-git-github](https://user-images.githubusercontent.com/58775072/86921400-762cd880-c101-11ea-9395-e123e5764daa.png) 185 | 186 | 187 | ### Caso ainda haja dúvidas 188 | 189 | - [Me envie um e-mail](mailto:alysson.barbosa@ee.ufcg.edu.br) 190 | --------------------------------------------------------------------------------