{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial para o módulo *aluno_exatas*\n", "\n", "Esse tutorial tem como objetivo explorar os módulos contidos no módulo `aluno_exatas`.\n", "\n", "Atualmente, os módulos disponíveis são:\n", "* [`aluno_exatas.fis_exp`](#aluno_exatas.fis_exp)\n", "* [`aluno_exatas.calc_num`](#aluno_exatas.calc_num)\n", "* [`aluno_exatas.circuitos_eletricos`](#aluno_exatas.circuitos_eletricos)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## *aluno_exatas.fis_exp*\n", "\n", "Esse módulo tem como objetivo auxiliar o aluno que está cursando física experimental. Além de automatizar a propagação, permite gerar funções que facilitam a manipulação dos dados medidos.\n", "\n", "### *aluno_exatas.fis\\_exp.FisExp*\n", "\n", "Essa classe é útil principalmente na propagação de incertezas.\n", "\n", "#### Importando módulos úteis:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import aluno_exatas.fis_exp as fe\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Inicializando o módulo\n", "\n", "A variável `f` irá conter um objeto `FisExp` cuja função principal é `a+b*c`. Nesse objeto, pode ser achada a propagação de incertezas da função principal." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Função principal: a**2 + b*c\n", "Variáveis da função principal: {c, b, a}\n", "\n", "Propagação de incertezas da função principal: sqrt(4*a**2*u_a**2 + b**2*u_c**2 + c**2*u_b**2)\n", "Incertezas da propagação de incertezas: [u_c, u_b, u_a]\n" ] } ], "source": [ "f = fe.FisExp('a**2+b*c')\n", "\n", "print (f'Função principal: {f.funcao}')\n", "print (f'Variáveis da função principal: {f.variaveis}\\n')\n", "print (f'Propagação de incertezas da função principal: {f.propagacao}')\n", "print (f'Incertezas da propagação de incertezas: {list(f.incertezas.values())}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Definindo valores conhecidos\n", "\n", "Nesse caso, os valores de `a` e `b` são constantes, assim como as incertezas de `a` e `c`. Os valores desconhecidos são `c` e a incerteza de `b`." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Função com valores constantes substituídos: 2*c + 16\n", "Propagação com valores constantes substituídos: sqrt(c**2*u_b**2 + 80)\n" ] } ], "source": [ "f.valores_conhecidos = {'a':4, 'b':2}\n", "f.incertezas_conhecidas = {'a':1, 'c':2}\n", "\n", "print (f'Função com valores constantes substituídos: {f.funcao_substituida}')\n", "print (f'Propagação com valores constantes substituídos: {f.propagacao_substituida}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Criação de funções\n", "\n", "Agora são criadas funções para calcular o valor da função principal e da propagação em diferentes valores de `c` e `u_b`." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Função principal avaliada em c=5: 26\n", "Propagação avaliada em c=5, u_b=1: 10.246950765959598\n" ] } ], "source": [ "f.gerar_funcao(['c'])\n", "f.gerar_propagacao(['c','u_b'])\n", "\n", "print (f'Função principal avaliada em c=5: {f.funcao_gerada(5)}')\n", "print (f'Propagação avaliada em c=5, u_b=1: {f.propagacao_gerada(5,1)}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Essas funções também podem ser utilizadas com valores armazenados em `numpy.arrays`, o que permite que sejam avaliadas em vários pontos. Quando os parâmetros das funções são vários `numpy.arrays`, a função é avaliada de forma sequencial, seguindo a sequência de cada array (portanto, os vetores precisam ter o mesmo tamanho)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Função principal avaliada em diferentes valores de c: [ 16. 41. 66. 91. 116.]\n", "Propagação avaliada em diferentes valores de c e u_b: [ 8.94427191 15.37042615 50.7937004 75.5314504 50.7937004 ]\n" ] } ], "source": [ "c = np.linspace(0,50,5)\n", "u_b = np.array([1,1,2,2,1])\n", "\n", "print (f'Função principal avaliada em diferentes valores de c: {f.funcao_gerada(c)}')\n", "print (f'Propagação avaliada em diferentes valores de c e u_b: {f.propagacao_gerada(c, u_b)}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Funcionalidades extra\n", "\n", "Se, por alguma razão, o usuário desejar integrar ou derivar a função principal, há funções que permitem isso." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Função derivada em relação a \"a\": 2*a\n", "Função derivada em relação a \"a\", avaliada em a=1, derivada de índice 2: 2\n", "Função derivada em relação a \"a\", com valores conhecidos substituídos: 8 \n", "\n", "Integral da função em relação a \"a\": a**3/3 + a*b*c\n", "Integral da função em relação a \"a\", avaliada entre [0,5]: 5*b*c + 125/3\n", "Integral da função em relação a \"c\", avaliada entre [0,5], com valores conhecidos substituídos: 105\n" ] } ], "source": [ "print ('Função derivada em relação a \"a\": ', f.derivar('a'))\n", "print ('Função derivada em relação a \"a\", avaliada em a=1, derivada de índice 2: ', f.derivar('a', ponto_avaliado=1, indice=2))\n", "print ('Função derivada em relação a \"a\", com valores conhecidos substituídos: ', f.derivar('a', substituir=True), '\\n')\n", "\n", "print ('Integral da função em relação a \"a\": ', f.integrar('a'))\n", "print ('Integral da função em relação a \"a\", avaliada entre [0,5]: ', f.integrar('a', limites=[0,5]))\n", "print ('Integral da função em relação a \"c\", avaliada entre [0,5], com valores conhecidos substituídos: ', f.integrar('c', limites=[0,5], substituir=True))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### *aluno_exatas.fis\\_exp.MMQ*\n", "\n", "Essa classe foi feita para facilitar a utilização do MMQ linear, com incertezas variáveis ou não.\n", "\n", "#### Importação de módulos\n", "\n", "O módulo `fis_exp` já foi importado, de forma que não é necessário importá-lo novamente.\n", "\n", "#### Inicializando o módulo\n", "\n", "O módulo pode ser inicializado de diferentes formas, dependendo de que tipo de MMQ se quer calcular." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "mmq_inc_iguais = fe.MMQ()\n", "mmq_inc_varia = fe.MMQ(fe.Incertezas.variaveis)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Definição de valores\n", "\n", "Os módulos podem receber `lists`, `numpy.ndarrays` ou números normais (no caso de `incerteza_y` para incertezas iguais)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "x = [0, 1, 2, 3, 4]\n", "y = np.array([1, 3, 7, 8, 10])\n", "\n", "mmq_inc_iguais.x_values = x\n", "mmq_inc_iguais.y_values = y\n", "mmq_inc_iguais.incertezas_y = 1\n", "\n", "mmq_inc_varia.x_values = x\n", "mmq_inc_varia.y_values = y\n", "mmq_inc_varia.incertezas_y = [1, 1, 2, 1, 3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Recebendo de volta os coeficientes\n", "\n", "Os coeficientes da função na forma `y = a + b*x` são retornados no formato `[a,b]`, assim como as incertezas." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Coeficientes da função com incerteza constante: [1.2 2.3]\n", "Incertezas dos coeficientes da função com incerteza constante: [0.77459667 0.31622777] \n", "\n", "Coeficientes da função com incerteza variável: [1.01265823 2.36075949]\n", "Incertezas dos coeficientes da função com incerteza variável: [0.65822785 0.14556962]\n" ] } ], "source": [ "coef_inc_iguais, incert_inc_iguais = mmq_inc_iguais.coeficientes()\n", "coef_inc_varia, incert_inc_varia = mmq_inc_varia.coeficientes()\n", "\n", "print ('Coeficientes da função com incerteza constante: ', coef_inc_iguais)\n", "print ('Incertezas dos coeficientes da função com incerteza constante:', incert_inc_iguais, '\\n')\n", "\n", "print ('Coeficientes da função com incerteza variável: ', coef_inc_varia)\n", "print ('Incertezas dos coeficientes da função com incerteza variável:', incert_inc_varia)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## *aluno_exatas.calc_num*\n", "\n", "Esse módulo tem como objetivo auxiliar o aluno que está cursando cálculo numérico. Contém funções que implementam conceitos aprendidos em aula.\n", "\n", "#### Importando módulos úteis:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import aluno_exatas.calc_num as cn\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Métodos de aproximações sucessivas para achar zero de funções\n", "\n", "#### Definindo a função que será usada e sua derivada\n", "\n", "A definição da derivada é necessária para o método de Newton." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def f(x):\n", " return x + np.cos(x)\n", "\n", "def flinha(x):\n", " return 1 - np.sin(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Definindo aproximações iniciais para os métodos da secante, newton e bissecção\n", "\n", "* O método da secante precisa apenas da própria função e de duas aproximações para a raiz;\n", "* O método de Newton precisa da função, sua derivada, e uma aproximação inicial;\n", "* O método da bissecção precisa própria função e de duas aproximações para o intervalo que contém a raiz." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Função inicial avaliada nas aproximações iniciais:\n", "f(-1) = -0.45969769413186023\n", "f(0) = 1.0\n", "f(1) = 1.5403023058681398\n" ] } ], "source": [ "x_secante = 0.0\n", "xo_secante = 1.0\n", "\n", "x_newton = 1.0\n", "\n", "a_bi = -1.0\n", "b_bi = 0.0\n", "\n", "print('Função inicial avaliada nas aproximações iniciais:')\n", "print(f'f(-1) = {f(-1)}')\n", "print(f'f(0) = {f(0)}')\n", "print(f'f(1) = {f(1)}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Testando cada um dos métodos\n", "\n", "Os métodos irão rodar por 9 iterações e será possível observar a qualidade da aproximação de cada um.\n", "\n", "O método da secante, que é sujeito a erros por estar realizando divisão por 0, evita isso retornando os mesmos valores de `x` e `xo` que foram utilizados como entrada da função." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Raiz encontrada pelo método da secante:\n", "x = -0.7390851332151607 | xo =-0.7390851332151607\n", "f(x) = 0.0 | f(xo) = 0.0\n", "\n", "Raiz encontrada pelo método de Newton:\n", "x = -0.7390851332151607\n", "f(x) = 0.0\n", "\n", "Intervalo encontrado pelo método da bissecção:\n", "Raiz está entre: (-0.7392578125, -0.73828125)\n", "f(a) = -0.0002890091467900868 | f(b) = 0.001345149751805108\n" ] } ], "source": [ "for i in range(10):\n", " x_secante, xo_secante = cn.metodo_secante(f, x_secante, xo_secante)\n", " \n", " x_newton = cn.metodo_newton(f, flinha, x_newton)\n", " \n", " a_bi, b_bi = cn.metodo_bisseccao(f, a_bi, b_bi)\n", "\n", "\n", "print('Raiz encontrada pelo método da secante:')\n", "print(f'x = {x_secante} | xo ={xo_secante}')\n", "print(f'f(x) = {f(x_secante)} | f(xo) = {f(xo_secante)}')\n", "\n", "print('\\nRaiz encontrada pelo método de Newton:')\n", "print(f'x = {x_newton}')\n", "print(f'f(x) = {f(x_newton)}')\n", "\n", "print('\\nIntervalo encontrado pelo método da bissecção:')\n", "print(f'Raiz está entre: {(a_bi, b_bi)}')\n", "print(f'f(a) = {f(a_bi)} | f(b) = {f(b_bi)}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## *aluno_exatas.circuitos_eletricos*\n", "\n", "Esse módulo tem como função auxiliar o aluno que está cursando circuitos elétricos. Sua principal função é a implementação de funções que facilitam o uso de fasores.\n", "\n", "#### Importando módulos úteis:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "import aluno_exatas.circuitos_eletricos as ce\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Fasores\n", "\n", "Essas funções permitem fazer a conversão entre números complexos nativos de Python e a representação fasorial (magnitude e defasagem).\n", "\n", "#### Importando as funções relativas a fasores:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "from aluno_exatas.circuitos_eletricos.fasores import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Definindo constantes para serem testadas\n", "\n", "Vamos definir o mesmo número em duas representações diferentes, e verificar que as funções utilizadas retornam a mesma coisa." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ângulo em radianos: 0.9273 e em graus: 53.1301\n" ] } ], "source": [ "numero_complexo = 3 + 4j\n", "\n", "magnitude = 5\n", "angulo_rad = np.arctan(4 / 3)\n", "angulo_deg = np.rad2deg(angulo_rad)\n", "\n", "print(f'Ângulo em radianos: {angulo_rad:1.4f} e em graus: {angulo_deg:1.4f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Funções do módulo\n", "\n", "O módulo define duas funções base:\n", "* `complexo_para_polar`;\n", "* `polar_para_complexo`.\n", "\n", "No entanto, essas funções têm nomes muito longos, e portanto é mais simples utilizar as versões com nomes simplificados:\n", "* `c2p`: converte números complexos para representação fasorial;\n", "* `p2c`: converte a representação fasorial para um número complexo;\n", "* `c2pr`: a mesma coisa que `c2p`, mas os ângulos são representados em radianos;\n", "* `p2cr`: a mesma coisa que `p2c`, mas os ângulos são representados em radianos;" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "O número (3+4j) em coordenadas polares utilizando graus é: (5.0, 53.13010235415598).\n", "O número (3+4j) em coordenadas polares utilizando radianos é: (5.0, 0.9272952180016122).\n", "\n", "O fasor de magnitude 5 e com defasagem 53.1301 graus ou 0.9273 rad é igual a (3+4j)\n" ] } ], "source": [ "print(f'O número {numero_complexo} em coordenadas polares utilizando graus é: {c2p(numero_complexo)}.')\n", "print(f'O número {numero_complexo} em coordenadas polares utilizando radianos é: {c2pr(numero_complexo)}.\\n')\n", "\n", "print(f'O fasor de magnitude {magnitude} e com defasagem {angulo_deg:1.4f} graus ou {angulo_rad:1.4f} rad é igual a {p2c(magnitude, angulo_deg):1.4}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Testando ida e volta das funções\n", "\n", "Dado que as funções aqui exploradas permitem a conversão entre duas representações, é de se esperar que elas permitam reverter uma conversão. Isso pode ser observado abaixo." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Número complexo - velho: (3+4j) e novo: (3+4j).\n", "\n", "Magnitude - velha: 5.0000 e nova: 5.0000.\n", "Ângulo em graus - velho: 53.1301 e novo: 53.1301.\n", "\n", "Magnitude - velha: 5.0000 e nova: 5.0000.\n", "Ângulo em radianos - velho: 0.9273 e novo: 0.9273.\n" ] } ], "source": [ "numero_complexo_novo = p2c(*c2p(numero_complexo))\n", "\n", "print(f'Número complexo - velho: {numero_complexo:1.4} e novo: {numero_complexo_novo:1.4}.\\n')\n", "\n", "\n", "magnitude_nova, angulo_deg_novo = c2p(p2c(magnitude, angulo_deg))\n", "\n", "print(f'Magnitude - velha: {magnitude:1.4f} e nova: {magnitude_nova:1.4f}.')\n", "print(f'Ângulo em graus - velho: {angulo_deg:1.4f} e novo: {angulo_deg_novo:1.4f}.\\n')\n", "\n", "\n", "magnitude_nova, angulo_rad_novo = c2pr(p2cr(magnitude, angulo_rad))\n", "\n", "print(f'Magnitude - velha: {magnitude:1.4f} e nova: {magnitude_nova:1.4f}.')\n", "print(f'Ângulo em radianos - velho: {angulo_rad:1.4f} e novo: {angulo_rad_novo:1.4f}.')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }