Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Tutorial básico Julia Python

497 views
ubuntu2004
Kernel: SageMath 9.4

FÍSICA EXPERIMENTAL - 2021-2 - PARTE II

Carga Horária: 4h

Prof João Marcello Pereira ([email protected])

Nesta parte vamos começar controle de fluxo, gráficos funções, raíses e resolução de sistemas lineares e não lineares. Antes, vamos configurar o display para unicode art:

%display unicode_art

CONTROLE DE FLUXO

Em várias situações, o código decide qual ou quais instruções deve executar para continuar a fluxo do programa. Neste caso, temos as estruturas de decisão e repetição. A estrutura de programação do SageMath é baseada em Python, com algumas diferenças quanto à sintaxe de alguns comandos.

ESTRUTURA DE DECISÃO

Condicional "SE" (IF)

O condicional if/else é uma estrutura utilizada para executar um bloco de código se uma determinada condição for satisfeita (verdadeira) e executar outro conjunto de instruções caso ela seja falsa.

{}

Exemplo 1: Escrever um código compara dois valores para as variáveis xx e yy e se xx for menor que y deve imprimir "x menor que y".

# usar valores aleatórios entre 0 e 10 com a função randrange para as variaveis x e y x = randrange(0,10) y = randrange(0,10) # valores de x e y print(x, y) # se x < y imprima 'x menor que y ' if x < y: print('x menor que y') # para cada execução teremos valores diferentes de x e y e consequentemente um novo teste condicional
6 4

Exemplo 2: Escrever um código compara dois valores para as variáveis xx e yy e se xx for menor que y deve imprimir "x menor que y", senão se xx for igual a yy imprima 'x igual a y'

# usar valores aleatórios entre 0 e 10 com a função randrange para as variaveis x e y x = randrange(0,10) y = randrange(0,10) # valores de x e y print(x, y) # se x < y imprima 'x menor que y, senão se x = y imprima 'x igual a y' if x < y: print('x menor que y') elif x == y: pritn('x igual a y') # para cada execução teremos valores diferentes de x e y e consequentemente um novo teste condicional é realizado
2 8 x menor que y

Exemplo 3: Escrever um código compara dois valores para as variáveis xx e yy e se xx for menor que y deve imprimir "x menor que y", senão se xx for igual a yy imprima 'x igual a y', senão imprima 'x maior que y'.

# usar valores aleatórios entre 0 e 10 com a função randrange para as variaveis x e y x = randrange(0,10) y = randrange(0,10) # valores de x e y print(x, y) # se x < y imprima 'x menor que y, senão se x = y imprima 'x igual a y', senão imprima 'x maior que y' if x < y: print('x menor que y') elif x == y: pritn('x igual a y') else: print('x maior que y') # para cada execução teremos valores diferentes de x e y e consequentemente um novo teste condicional é realizado
5 7 x menor que y

Exemplo 3: Codifique a função definida como: f(x)={x2; x0x+1; x<0 f(x) = \begin{cases} x^2 &; ~ x \geq 0\\ x + 1 &; ~ x < 0 \end{cases}

# usar valores aleatórios de x x = randrange(-10, 10) #imprimir o valor de x print(x) # se x maior ou igual a 0 imprima x^2, senão se x menor que 0 imprima x + 1 if x >= 0: print('valor de x^2: ', x^2) elif x < 0: print('valor de x + 1: ', x)
9 valor de x^2: 81

ESTRURA DE REPETIÇÃO

Repetição "PARA" (FOR)

Um laço for\textbf{for} executa repetidamente um bloco de código um número fixo de vezes. A linguagem Python define a instrução else como uma estrutura dependente da instrução FORFOR cujo funcionamento novamente é análogo ao estudado na instrução IFIF.Estrutura:

Exemplo 1: Aplicar 10 valores de xx na expressão y=(x22)y = (x^2 - 2).

# lista de dados da variável x x_dados = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # laço 'for' for x in x_dados: print(x^2 - 2)
-2 -1 2 7 14 23 34 47 62 79

Método bruto de encontrar raízes de uma função sem otimização

A partir de uma função y(s)y(s) o método bruto permite encontrar todas as raízes em um intervalo. Para isto, basta substituir xx por valores bem pequenos na função e testar a tolerância (valor de yy próximo de zero), que se for menor que um determinado valor, temos então uma raiz.

Exemplo 2: de acordo com a função f(x)=sin(5x)x+0.1f(x) = sin(5x)x + 0.1, determinar todas as raízes da função f(x)f(x) no intervalo 0x3 0 \leq x \leq 3

# calcular o tempo de processamento %%time # passo: pequenos encrementos no valor de 'x' passo = 1e-6 # tolerância tolerancia = 1e-5 # laço 'for' for x in srange(0, 3, passo): if abs(sin(5*x)*x + 0.1 ) < tolerancia : print("Valor(y):", n(sin(5*x)*x + 0.1, digits = 6)," . Raiz(x): ", n(x, digits = 6)) print('fim')
Valor(y): 9.55477e-6 . Raiz(x): 0.658792 Valor(y): 6.14719e-6 . Raiz(x): 0.658793 Valor(y): 2.73961e-6 . Raiz(x): 0.658794 Valor(y): -6.67989e-7 . Raiz(x): 0.658795 Valor(y): -4.07559e-6 . Raiz(x): 0.658796 Valor(y): -7.48320e-6 . Raiz(x): 0.658797 Valor(y): -5.96600e-6 . Raiz(x): 1.24050 Valor(y): 1.35678e-7 . Raiz(x): 1.24050 Valor(y): 6.23737e-6 . Raiz(x): 1.24050 Valor(y): 6.97767e-6 . Raiz(x): 1.89551 Valor(y): -2.53945e-6 . Raiz(x): 1.89551 Valor(y): 1.36964e-6 . Raiz(x): 2.50529 fim CPU times: user 31.6 s, sys: 254 ms, total: 31.9 s Wall time: 32.6 s

Repetição "ENQUANTO" (WHILE)

Um laço while\textbf{while} executa um bloco de código enquanto uma condição ainda está satisfeita. A linguagem Python define a instrução else como uma estrutura dependente da instrução WHILEWHILE cujo funcionamento novamente é análogo ao estudado na instrução IFIF.Estrutura:

Exemplo 1: a partir de uma matriz de dados, pesquise se o número 132 pertence à matriz de dados abaixo

Exemplo 1: Encontrar os nn números primos entre 0 e 30.

n = 0 while n < 30: if is_prime(n): print(n) n=n+1
2 3 5 7 11 13 17 19 23 29

Continue e Break

A instrução continue interrompe o processamento atual e pula para a próxima iteração. Break interrompe totalmente o loop.

Exemplo 2: Encontrar o primeiro número primo entre 0 e 30 maior que 10. Ao encontrar o número primo o laço deve ser interrompido.

n = 0 while n < 30: if is_prime(n) & (n > 10): print(n) break n = n + 1
11

Exemplo 3 Encontrar os nn números primos entre 0 e 30 maiores que 10. Quando encontrar um número primo o laço deve continuar para encontrar outros números primos.

n = 0 while n < 30: if is_prime(n) & (n > 10): print(n) n = n + 1 continue n = n + 1
11 13 17 19 23 29

FUNÇÃO

Função, de acordo com a definição matemática, é uma correspondência unívoca entre dois conjuntos em que a cada elemento do primeiro conjunto corresponde a um e somente um elemento do segundo. Dessa forma, temos que uma função é uma relação entre das variáveis, sendo uma dependente e outra independente. Ex: y(x)=x+2,z=xy2x,f(x)=x2+y2y(x) = x + 2, z = xy - 2x, f(x) = x^2 + y^2. No campo da computação, Tucker & Noonan(2009) informam que "em linguagens diferentes, as funções são conhecidas variavelmente como procedimentos, sub-rotinas, subprogramas ou métodos, e possuem diversas características em comum, assim como algumas diferenças importantes nas mais variadas linguagens". De modo geral, uma função é segmento do código que contém um conjunto de instruções que pode ou não receber argumentos e retornar um ou vários valores processados.

Para definir uma nova função no CoCalc de duas maneiras:

  • forma reduzida - utilizada de forma semelhante a definição matemática de função.

função_nome(argumento(s)) = instruções
  • Forma tradicional - use o comando def e dois pontos após a lista de nomes das variáveis. Em Python, blocos de código não são indicados por colchetes ou blocos de início e fim, como em outras linguagens. Em vez disso, blocos de código são indicados por identação, que devem estar alinhadas exatamente.

def função_nome(argumento(s)) instruções return

Cuidado com a identação!

Exemplo 1: Codificar uma função chamada 'areaC' que calcule o cálculo de um círculo a partir do valor do raio.

# Função cálculo área do circulo def areaC(r): return pi*r^2
# Calculo da área para r = 5 areaC(5)
25*pi
# Valor numérico do cálculo da área areaC(5).n()
78.5398163397448

Exemplo 2: Codificar a função simplificada chamada 'fareaC' que calcula a área do círculo.

# Função simplificada do cálculo da área do circulo fareaC(r) = pi*r^2
# Calculo da área para r = 5 fareaC(5)
25*pi
# Valor numérico do cálculo da área fareaC(5).n()
78.5398163397448

GRÁFICOS 2D E 3D

# resetar variáveis reset()
# dados x_dados = [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0] y_dados = [0.0, 0.5, 0.84, 1.0, 0.91, 0.6, 0.14, -0.35, -0.76, -0.98] len(x_dados) == len(y_dados)
True

Gráficos pontos discretos e espalhamento

# gráfico pontos discretos points(zip(x_dados, y_dados), axes_labels = ['x','y'])
Image in a Jupyter notebook
# gráfico espalhamento scatter_plot([[x_dados, y_dados]], axes_labels = ['x','y'])
Image in a Jupyter notebook
# gráfico melhorado com axes_labels = ['x','y'], gridlines = "minor", figsize = (5, 4) scatter_plot([[x_dados, y_dados]], axes_labels = ['x','y'], gridlines = "minor", figsize = (5, 4))
Image in a Jupyter notebook

Gráfico de funções

# Funções f1(x) = sin(x)*x e f2(x) = cos(x)*sqrt(x) f1(x) = sin(x)*x f2(x) = cos(x)*sqrt(x)
# Gráfico funções f1 e f2 plot(f1(x), (x, -10, 10), axes_labels = ['x','y'], gridlines = "minor", figsize = (5, 4)) + plot(f2(x), (x, -10, 10), color = 'red')
verbose 0 (3797: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points. verbose 0 (3797: plot.py, generate_plot_points) Last error message: 'math domain error'
Image in a Jupyter notebook
# Gráfico funções f1 e f2 com preenchimento (f2) plot(f1(x), (x, -10, 10), axes_labels = ['x','y'], gridlines = "minor", figsize = (5, 4)) + plot(f2(x), (x, -10, 10), color = 'red', fill = 'axis')
verbose 0 (3797: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points. verbose 0 (3797: plot.py, generate_plot_points) Last error message: 'math domain error'
Image in a Jupyter notebook
# Gráfico funções f1 com pontos (2.5, f1(2.5)) e (3, f1(3)) em destaque plot(f1(x), (x, -10, 10), axes_labels = ['x','y'], gridlines = "minor", figsize = (5, 4)) + points([(2.5, f1(2.5)) , (3, f1(3)) ], color = 'red', size = 30)
Image in a Jupyter notebook

Gráfico implícito

# circunferência var('y') implicit_plot(x^2 + y^2 - 4,(x,-2, 2),(y,-2, 2), axes_labels=['x','y'], gridlines = 'minor')
Image in a Jupyter notebook
# elipse implicit_plot(x^2/9 + y^2/4 - 1,(x,-3, 3),(y,-2, 2), axes_labels=['x','y'], gridlines = 'minor')
Image in a Jupyter notebook

Gráfico 3D

# Gráfico 3d f(x, y) = cos(y^2 + x^2)*x^2 + sin(x^2) com color = 'green', mesh = True var('y') plot3d(cos(y^2 + x^2)*x^2 + sin(x^2) , (x, -2, 2), (y, -2, 2), color = 'green', mesh = True)

RAÍZES

De acordo com o dicionario matemático disponível em "http://www.somatematica.com.br/dicionarioMatematico" temos que:

Equação: Expressão algébrica indicada por uma igualdade, onde há valores desconhecidos expressos por letras (incógnitas). Logo, todo conjunto de expressões no qual há uma igualdade cuja(s) incógita(s) satisfaçam a um conjunto limitado de soluções, então temos uma equação. Ex: x+2=0,  xy2x=2,  x2+y2=22x + 2 =0, ~~ xy - 2x = 2,~~ x^2 + y^2 = 2^2.

%display latex
reset()

Exemplo 1: Calcular as raízes da função f(x)=x2+2x+9f(x) = -x^2 + 2x + 9

# gráfico da função plot(x^2 + x - 9, (x, -5, 5), gridlines='minor', figsize=(6,4))
Image in a Jupyter notebook
sol = solve(x^2 + x - 9, x) sol
[x == -1/2*sqrt(37) - 1/2, x == 1/2*sqrt(37) - 1/2]
sol[1]
1 √37 x = - ─ + ─── 2 2
sol[1].rhs()
1 √37 - ─ + ─── 2 2
sol[1].rhs().n()
2.54138126514911

Método numérico para determinar raízes

Em algumas situações, a função solve() ao tentar resolver uma equação, pode retornar somente dois colchetes [] ou a frase NotImplementedError. Nestes caso, isto significa que o método empregado pela função não conseguiu encontrar uma solução, porém ela poderá existir e se existir será encontrada numericamente. Sintaxe:

find_root(função/expressão, a, b) a, b: intervalo que contém a raiz

Exemplo 1: De acordo com a fução y(x)=1+x+cos(x+1)x y(x) = 1 + x + cos(x + 1)x~ resolver  y(x)=0~y(x) = 0

reset()
# definição da função y(x) = 1 + x + cos(x + 1)*x
# gráfico da função plot(y(x), (x, -7, 7), gridlines='minor')
Image in a Jupyter notebook
# resolver simbolicamente solve(y(x), x)
[x == -1/(cos(x + 1) + 1)]

veja que a função solve() não conseguiu encontrar simbolicamente uma solução. A solução é encontrar individualmente as raízes utilizando um método numérico para cada conjunto de intervalos que contém uma raíz.

# entre -6 e -4 há uma raiz find_root(y(x), -12, -10.5)
-10.85733606948584
# entre -4 e -2 há uma raiz find_root(y(x), -4, -2)
-3.3480408751943203

Aplicação na física

Um carro de laboratório controlado por um arduino, possui implementado as funções posição de velocidade em função do tempo para controlar o movimento do carro em linha reta. Considerando v0=0.2m/sv_0 = 0.2m/s, x0=0mx_0 = 0m, a=0.02m/s2a = -0.02m/s², e que o carro ao ser solto vai até um certa posição em linha reta e depois retorna, calcule:

%display unicode_art

a) Defina as variáveis e as funções v(t) e x(t)x(t)

# criar variável simbólica tempo t var('t') # criar as variáveis para aceleração, volocidade inicial e posição inicial a = -0.02 v0 = 0.2 x0 = 0.0 # função velocidade v(t) = v0 + a*t # função posição x(t) = x0 + v0*t + a*t^2/2
# verificar as função v(t), x(t)
⎛ 2 ⎞ ⎝ 0.2 - 0.02⋅t, - 0.01⋅t + 0.2⋅t ⎠

b) Qual o intervalo de tempo para ir e voltar ao ponto de partida

# tempo do carro para ir e voltar T = solve(x(t) == 0.0, t) T # note que T é uma lsta de dados contendo dois tempos, t_1 = 0s e t_2 = 20s
<ipython-input-200-68ff43cbad19>:3: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) See http://trac.sagemath.org/5930 for details. T = solve(x(t) == RealNumber('0.0'), t)
[t == 0]
# dividindo a lista T em duas variáveis t1 e t2 t1 = T[0].rhs() t2 = T[1].rhs() #imprimindo os valores dos tempos de t1 e t2 t1, t2
( 0, 20 )

c) os gráficos da função posição e função velocidade

# gráfico da função x(t) no intervalo de 0 a 21s com axes_labels = ['x','y'], color = "red", gridlines = "minor", figsize = (4, 3) plot(x(t), (t, t1, t2), axes_labels = ['t(s)','x(m)'], color = "red", gridlines = "minor", figsize = (4, 3))
Image in a Jupyter notebook
# gráfico da função v(t) com axes_labels = ['x','y'], color = "red", gridlines = "minor", figsize = (4, 3) plot(v(t), (t, t1, t2), axes_labels = ['t(s)','v(m/s)'], color = "red", gridlines = "minor", figsize = (4, 3))
Image in a Jupyter notebook

c) o tempo em que o carro muda de sentido

# o carro muda de sentido quando a velocidade é zero solve(v(t) == 0.0, t)
[t == 10]

d) calcular o instante quando a velocidade e a posição são  0,17m/s~-0,17m/s e  0,7m~0,7m respectivamente.

solve(v(t) == -0.17, t)[0].rhs().n()
18.5000000000000
# testando v(18.5)
-0.170000000000000
solve(x(t) == 1.0, t)[0].rhs().n()
10.0000000000000
# testando x(10)
1.00000000000000

Mínimo e máximo local

Sintaxe:

find_local_minimum(função/expressão, a, b)

sendo:

  • função/expressão:

  • a, b:

# definição da função y(x) = 1 + x + cos(x + 1)*x
# gráfico da função plot(y(x), (x, -7, 7), gridlines='minor')
Image in a Jupyter notebook

# mínimo local find_local_minimum(y(x), -5, 0)
( -2.0842856544140256, -1.9483784230960277 )
# máximo local find_local_maximum(y(x), -5, 0)
( 1.0, -4.141592651731468 )

SISTEMAS DE EQUAÇÕES LINEARES

 { 2y+8x=50.5y3x=2 ~ \begin{cases} \ 2y + 8x = 5\\ -0.5y - 3x = -2 \end{cases} ~

Sintaxe:

solve([eq_1, eq_1, ..., eq_n], [var_1, var_2, ..., var_n])

Exemplo 1: Resolver o sistema de equações lineares

# definir a variável simbólica var('y') # definir as funções do distema de equações eq1(x, y) = 2.0*x + 8.0*y -5.0 eq2(x, y) = -0.5*y -3.0*x + 2.0
# Gráfico implícito de eq1 e eq2 com axes_labels = ['x','y'] e gridlines = 'minor' implicit_plot(eq1(x, y), (x,-5,5), (y,-5,5)) + implicit_plot(eq2(x, y), (x,-5,5), (y,-5,5), color = 'red', axes_labels = ['x', 'y'], gridlines = 'minor')
Image in a Jupyter notebook
# Solução do sistema sol_ln = solve([eq1, eq2], [x, y]) sol_ln
[[x == (27/46), y == (11/23)]]
# definir as variáveis x e y que receberão os valores calculados x = sol_ln[0][0].rhs().n() y = sol_ln[0][1].rhs().n()
# imprimir as variáveis x, y
( 0.586956521739130, 0.478260869565217 )

Sistemas Equações Não Lineares

 { y2+8x=0x28y=2 ~ \begin{cases} \ y^2 + 8x = 0\\ -x^2 -8y = 2 \end{cases} ~

Exemplo 2: Resolver o sistema de equações não lineares

# definir as funções do sistema de equações não lineares eq3(x, y) = y^2 + 8*x eq4(x, y) = -x^2 -8*y -2
# Gráfico implícito com color = 'red', axes_labels = ['x','y'] e gridlines = 'minor' implicit_plot(eq3(x, y), (x,-10, 10), (y,-10, 10)) + implicit_plot(eq4(x, y), (x,-10, 10), (y,-10, 10), axes_labels = ['x', 'y'], color = 'red', gridlines = 'minor')
Image in a Jupyter notebook

Veja que temos duas soluções para os sistema, sendo os valores aproximados: x1=0 e y1=0.1  ;  x2=8 e y2=8x_1 = 0 ~e~ y_1 = -0.1~~;~~x_2 = -8 ~e~ y_2 = -8

# Solução solnl solnl = solve([eq3(x, y), eq4(x, y)], [x, y]) solnl
[[x == -0.00781297686626381, y == -0.2500076305588621], [x == -7.830640958832725, y == -7.914868105515588], [x == (3.919227064207133 - 7.072470694459699*I), y == (4.082437617897199 + 6.929654639134567*I)], [x == (3.919227064207133 + 7.072470694459699*I), y == (4.082437617897199 - 6.929654639134567*I)]]
# primeiro conjunto solução solnl[0][0], solnl[0][1]
( x = -0.00781297686626381, y = -0.250007630558862 )
# primeiro conjunto solução somente os valores solnl[0][0].rhs() , solnl[0][1].rhs()
( -0.00781297686626381, -0.2500076305588621 )

REFÊNCIAS BIBLIOGRÁFICAS

TUCKER, Allen B. ; NOONAN, Robert E. Linguagens de Programação : Princípios e Paradigmas. 2. ed. São Paulo, SP: McGraw-Hill, 2009. 600 p.