Álgebra Elementar e Cálculo¶
O Sage pode realizar diversos cálculos em álgebra elementar e cálculo diferencial e integral: por exemplo, encontrar soluções de equações, diferenciar, integrar, e calcular a transformada de Laplace. Veja a documentação em Sage Constructions para mais exemplos.
Resolvendo equações¶
Resolvendo equações exatamente¶
A função solve
resolve equações. Para usá-la, primeiro especifique
algumas variáveis; então os argumentos de solve
são uma equação
(ou um sistema de equações), juntamente com as variáveis para as
quais resolver:
sage: x = var('x')
sage: solve(x^2 + 3*x + 2, x)
[x == -2, x == -1]
>>> from sage.all import *
>>> x = var('x')
>>> solve(x**Integer(2) + Integer(3)*x + Integer(2), x)
[x == -2, x == -1]
x = var('x') solve(x^2 + 3*x + 2, x)
Você pode resolver equações para uma variável em termos das outras:
sage: x, b, c = var('x b c')
sage: solve([x^2 + b*x + c == 0],x)
[x == -1/2*b - 1/2*sqrt(b^2 - 4*c), x == -1/2*b + 1/2*sqrt(b^2 - 4*c)]
>>> from sage.all import *
>>> x, b, c = var('x b c')
>>> solve([x**Integer(2) + b*x + c == Integer(0)],x)
[x == -1/2*b - 1/2*sqrt(b^2 - 4*c), x == -1/2*b + 1/2*sqrt(b^2 - 4*c)]
x, b, c = var('x b c') solve([x^2 + b*x + c == 0],x)
Você pode resolver para diversas variáveis:
sage: x, y = var('x, y')
sage: solve([x+y==6, x-y==4], x, y)
[[x == 5, y == 1]]
>>> from sage.all import *
>>> x, y = var('x, y')
>>> solve([x+y==Integer(6), x-y==Integer(4)], x, y)
[[x == 5, y == 1]]
x, y = var('x, y') solve([x+y==6, x-y==4], x, y)
O seguinte exemplo, que mostra como usar o Sage para resolver um sistema de equações não-lineares, foi sugerido por Jason Grout: primeiro, resolvemos o sistemas simbolicamente:
sage: var('x y p q')
(x, y, p, q)
sage: eq1 = p+q==9
sage: eq2 = q*y+p*x==-6
sage: eq3 = q*y^2+p*x^2==24
sage: solve([eq1,eq2,eq3,p==1],p,q,x,y)
[[p == 1, q == 8, x == -4/3*sqrt(10) - 2/3, y == 1/6*sqrt(10) - 2/3], [p == 1, q == 8, x == 4/3*sqrt(10) - 2/3, y == -1/6*sqrt(10) - 2/3]]
>>> from sage.all import *
>>> var('x y p q')
(x, y, p, q)
>>> eq1 = p+q==Integer(9)
>>> eq2 = q*y+p*x==-Integer(6)
>>> eq3 = q*y**Integer(2)+p*x**Integer(2)==Integer(24)
>>> solve([eq1,eq2,eq3,p==Integer(1)],p,q,x,y)
[[p == 1, q == 8, x == -4/3*sqrt(10) - 2/3, y == 1/6*sqrt(10) - 2/3], [p == 1, q == 8, x == 4/3*sqrt(10) - 2/3, y == -1/6*sqrt(10) - 2/3]]
var('x y p q') eq1 = p+q==9 eq2 = q*y+p*x==-6 eq3 = q*y^2+p*x^2==24 solve([eq1,eq2,eq3,p==1],p,q,x,y)
Para obter soluções numéricas aproximadas, podemos usar:
sage: solns = solve([eq1,eq2,eq3,p==1],p,q,x,y, solution_dict=True)
sage: [[s[p].n(30), s[q].n(30), s[x].n(30), s[y].n(30)] for s in solns]
[[1.0000000, 8.0000000, -4.8830369, -0.13962039],
[1.0000000, 8.0000000, 3.5497035, -1.1937129]]
>>> from sage.all import *
>>> solns = solve([eq1,eq2,eq3,p==Integer(1)],p,q,x,y, solution_dict=True)
>>> [[s[p].n(Integer(30)), s[q].n(Integer(30)), s[x].n(Integer(30)), s[y].n(Integer(30))] for s in solns]
[[1.0000000, 8.0000000, -4.8830369, -0.13962039],
[1.0000000, 8.0000000, 3.5497035, -1.1937129]]
solns = solve([eq1,eq2,eq3,p==1],p,q,x,y, solution_dict=True) [[s[p].n(30), s[q].n(30), s[x].n(30), s[y].n(30)] for s in solns]
(A função n
imprime uma aproximação numérica, e o argumento é o
número de bits de precisão.)
Resolvendo Equações Numericamente¶
Frequentemente, solve
não será capaz de encontrar uma solução
exata para uma equação ou sistema de equações. Nesse caso, você pode
usar find_root
para encontrar uma solução numérica. Por exemplo,
solve
não encontra uma solução para a equação abaixo:
sage: theta = var('theta')
sage: solve(cos(theta)==sin(theta), theta)
[sin(theta) == cos(theta)]
>>> from sage.all import *
>>> theta = var('theta')
>>> solve(cos(theta)==sin(theta), theta)
[sin(theta) == cos(theta)]
theta = var('theta') solve(cos(theta)==sin(theta), theta)
Por outro lado, podemos usar find_root
para encontrar uma solução
para a equação acima no intervalo
sage: phi = var('phi')
sage: find_root(cos(phi)==sin(phi),0,pi/2)
0.785398163397448...
>>> from sage.all import *
>>> phi = var('phi')
>>> find_root(cos(phi)==sin(phi),Integer(0),pi/Integer(2))
0.785398163397448...
phi = var('phi') find_root(cos(phi)==sin(phi),0,pi/2)
Diferenciação, Integração, etc.¶
O Sage é capaz de diferenciar e integrar diversas funções. Por
exemplo, para diferenciar
sage: u = var('u')
sage: diff(sin(u), u)
cos(u)
>>> from sage.all import *
>>> u = var('u')
>>> diff(sin(u), u)
cos(u)
u = var('u') diff(sin(u), u)
Para calcular a quarta derivada de
sage: diff(sin(x^2), x, 4)
16*x^4*sin(x^2) - 48*x^2*cos(x^2) - 12*sin(x^2)
>>> from sage.all import *
>>> diff(sin(x**Integer(2)), x, Integer(4))
16*x^4*sin(x^2) - 48*x^2*cos(x^2) - 12*sin(x^2)
diff(sin(x^2), x, 4)
Para calcular as derivadas parciais de
sage: x, y = var('x,y')
sage: f = x^2 + 17*y^2
sage: f.diff(x)
2*x
sage: f.diff(y)
34*y
>>> from sage.all import *
>>> x, y = var('x,y')
>>> f = x**Integer(2) + Integer(17)*y**Integer(2)
>>> f.diff(x)
2*x
>>> f.diff(y)
34*y
x, y = var('x,y') f = x^2 + 17*y^2 f.diff(x) f.diff(y)
Passamos agora para integrais, tanto indefinidas como definidas. Para
calcular
sage: integral(x*sin(x^2), x)
-1/2*cos(x^2)
sage: integral(x/(x^2+1), x, 0, 1)
1/2*log(2)
>>> from sage.all import *
>>> integral(x*sin(x**Integer(2)), x)
-1/2*cos(x^2)
>>> integral(x/(x**Integer(2)+Integer(1)), x, Integer(0), Integer(1))
1/2*log(2)
integral(x*sin(x^2), x) integral(x/(x^2+1), x, 0, 1)
Para calcular a decomposição em frações parciais de
sage: f = 1/((1+x)*(x-1))
sage: f.partial_fraction(x)
-1/2/(x + 1) + 1/2/(x - 1)
>>> from sage.all import *
>>> f = Integer(1)/((Integer(1)+x)*(x-Integer(1)))
>>> f.partial_fraction(x)
-1/2/(x + 1) + 1/2/(x - 1)
f = 1/((1+x)*(x-1)) f.partial_fraction(x)
Resolvendo Equações Diferenciais¶
Você pode usar o Sage para investigar equações diferenciais
ordinárias. Para resolver a equação
sage: t = var('t') # define a variable t
sage: x = function('x')(t) # define x to be a function of that variable
sage: DE = diff(x, t) + x - 1
sage: desolve(DE, [x,t])
(_C + e^t)*e^(-t)
>>> from sage.all import *
>>> t = var('t') # define a variable t
>>> x = function('x')(t) # define x to be a function of that variable
>>> DE = diff(x, t) + x - Integer(1)
>>> desolve(DE, [x,t])
(_C + e^t)*e^(-t)
t = var('t') # define a variable t x = function('x')(t) # define x to be a function of that variable DE = diff(x, t) + x - 1 desolve(DE, [x,t])
Esse método usa a interface do Sage para o Maxima [Max]. Logo, o
formato dos resultados é um pouco diferente de outros cálculos
realizados no Sage. Nesse caso, o resultado diz que a solução geral da
equação diferencial é
Você pode calcular a transformada de Laplace também; a transformada de
Laplace de
sage: s = var("s")
sage: t = var("t")
sage: f = t^2*exp(t) - sin(t)
sage: f.laplace(t,s)
-1/(s^2 + 1) + 2/(s - 1)^3
>>> from sage.all import *
>>> s = var("s")
>>> t = var("t")
>>> f = t**Integer(2)*exp(t) - sin(t)
>>> f.laplace(t,s)
-1/(s^2 + 1) + 2/(s - 1)^3
s = var("s") t = var("t") f = t^2*exp(t) - sin(t) f.laplace(t,s)
A seguir, um exemplo mais complicado. O deslocamento, com respeito à posição de equilíbrio, de duas massas presas a uma parede através de molas, conforme a figura abaixo,
|------\/\/\/\/\---|massa1|----\/\/\/\/\/----|massa2|
mola1 mola2
é modelado pelo sistema de equações diferenciais de segunda ordem
onde, para
Exemplo: Use o Sage para resolver o problema acima com
Solução: Primeiramente, calcule a transformada de Laplace da primeira
equação (usando a notação
sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)")
sage: lde1 = de1.laplace("t","s"); lde1.sage()
2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0)
>>> from sage.all import *
>>> de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)")
>>> lde1 = de1.laplace("t","s"); lde1.sage()
2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0)
de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") lde1 = de1.laplace("t","s"); lde1.sage()
O resultado é um pouco difícil de ler, mas diz que
(onde a transformada de Laplace de uma função em letra minúscula
sage: t,s = SR.var('t,s')
sage: x = function('x')
sage: y = function('y')
sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t)
sage: f.laplace(t,s)
2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0)
>>> from sage.all import *
>>> t,s = SR.var('t,s')
>>> x = function('x')
>>> y = function('y')
>>> f = Integer(2)*x(t).diff(t,Integer(2)) + Integer(6)*x(t) - Integer(2)*y(t)
>>> f.laplace(t,s)
2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0)
t,s = SR.var('t,s') x = function('x') y = function('y') f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) f.laplace(t,s)
O resultado significa que
Em seguida, substitua a condição inicial para
sage: var('s X Y')
(s, X, Y)
sage: eqns = [(2*s^2+6)*X-2*Y == 6*s, -2*X +(s^2+2)*Y == 3*s]
sage: solve(eqns, X,Y)
[[X == 3*(s^3 + 3*s)/(s^4 + 5*s^2 + 4),
Y == 3*(s^3 + 5*s)/(s^4 + 5*s^2 + 4)]]
>>> from sage.all import *
>>> var('s X Y')
(s, X, Y)
>>> eqns = [(Integer(2)*s**Integer(2)+Integer(6))*X-Integer(2)*Y == Integer(6)*s, -Integer(2)*X +(s**Integer(2)+Integer(2))*Y == Integer(3)*s]
>>> solve(eqns, X,Y)
[[X == 3*(s^3 + 3*s)/(s^4 + 5*s^2 + 4),
Y == 3*(s^3 + 5*s)/(s^4 + 5*s^2 + 4)]]
var('s X Y') eqns = [(2*s^2+6)*X-2*Y == 6*s, -2*X +(s^2+2)*Y == 3*s] solve(eqns, X,Y)
Agora calcule a transformada de Laplace inversa para obter a resposta:
sage: var('s t')
(s, t)
sage: inverse_laplace((3*s^3 + 9*s)/(s^4 + 5*s^2 + 4),s,t)
cos(2*t) + 2*cos(t)
sage: inverse_laplace((3*s^3 + 15*s)/(s^4 + 5*s^2 + 4),s,t)
-cos(2*t) + 4*cos(t)
>>> from sage.all import *
>>> var('s t')
(s, t)
>>> inverse_laplace((Integer(3)*s**Integer(3) + Integer(9)*s)/(s**Integer(4) + Integer(5)*s**Integer(2) + Integer(4)),s,t)
cos(2*t) + 2*cos(t)
>>> inverse_laplace((Integer(3)*s**Integer(3) + Integer(15)*s)/(s**Integer(4) + Integer(5)*s**Integer(2) + Integer(4)),s,t)
-cos(2*t) + 4*cos(t)
var('s t') inverse_laplace((3*s^3 + 9*s)/(s^4 + 5*s^2 + 4),s,t) inverse_laplace((3*s^3 + 15*s)/(s^4 + 5*s^2 + 4),s,t)
Portanto, a solução é
Ela pode ser representada em um gráfico parametricamente usando os comandos
sage: t = var('t')
sage: P = parametric_plot((cos(2*t) + 2*cos(t), 4*cos(t) - cos(2*t) ),
....: (t, 0, 2*pi), rgbcolor=hue(0.9))
sage: show(P)
>>> from sage.all import *
>>> t = var('t')
>>> P = parametric_plot((cos(Integer(2)*t) + Integer(2)*cos(t), Integer(4)*cos(t) - cos(Integer(2)*t) ),
... (t, Integer(0), Integer(2)*pi), rgbcolor=hue(RealNumber('0.9')))
>>> show(P)
t = var('t') P = parametric_plot((cos(2*t) + 2*cos(t), 4*cos(t) - cos(2*t) ), (t, 0, 2*pi), rgbcolor=hue(0.9)) show(P)
As componentes individuais podem ser representadas em gráfico usando
sage: t = var('t')
sage: p1 = plot(cos(2*t) + 2*cos(t), (t,0, 2*pi), rgbcolor=hue(0.3))
sage: p2 = plot(4*cos(t) - cos(2*t), (t,0, 2*pi), rgbcolor=hue(0.6))
sage: show(p1 + p2)
>>> from sage.all import *
>>> t = var('t')
>>> p1 = plot(cos(Integer(2)*t) + Integer(2)*cos(t), (t,Integer(0), Integer(2)*pi), rgbcolor=hue(RealNumber('0.3')))
>>> p2 = plot(Integer(4)*cos(t) - cos(Integer(2)*t), (t,Integer(0), Integer(2)*pi), rgbcolor=hue(RealNumber('0.6')))
>>> show(p1 + p2)
t = var('t') p1 = plot(cos(2*t) + 2*cos(t), (t,0, 2*pi), rgbcolor=hue(0.3)) p2 = plot(4*cos(t) - cos(2*t), (t,0, 2*pi), rgbcolor=hue(0.6)) show(p1 + p2)
Leia mais sobre gráficos em Gráficos. Veja a seção 5.5 de [NagleEtAl2004] (em inglês) para mais informações sobre equações diferenciais.
Método de Euler para Sistemas de Equações Diferenciais¶
No próximo exemplo, vamos ilustrar o método de Euler para EDOs de primeira e segunda ordem. Primeiro, relembramos a ideia básica para equações de primeira ordem. Dado um problema de valor inicial da forma
queremos encontrar o valor aproximado da solução em
Da definição de derivada segue que
onde
Se chamarmos
Se dividirmos o intervalo de a até b em n partes, de modo que
… |
||
… |
||
… |
||
??? |
… |
O objetivo é completar os espaços em branco na tabela, em uma linha
por vez, até atingirmos ???, que é a aproximação para
A ideia para sistemas de EDOs é semelhante.
Exemplo: Aproxime numericamente
Devemos reduzir a EDO de segunda ordem a um sistema de duas EDOs de
primeira ordem (usando
sage: t,x,y = PolynomialRing(RealField(10),3,"txy").gens()
sage: f = y; g = -x - y * t
sage: eulers_method_2x2(f,g, 0, 1, 0, 1/4, 1)
t x h*f(t,x,y) y h*g(t,x,y)
0 1 0.00 0 -0.25
1/4 1.0 -0.062 -0.25 -0.23
1/2 0.94 -0.12 -0.48 -0.17
3/4 0.82 -0.16 -0.66 -0.081
1 0.65 -0.18 -0.74 0.022
>>> from sage.all import *
>>> t,x,y = PolynomialRing(RealField(Integer(10)),Integer(3),"txy").gens()
>>> f = y; g = -x - y * t
>>> eulers_method_2x2(f,g, Integer(0), Integer(1), Integer(0), Integer(1)/Integer(4), Integer(1))
t x h*f(t,x,y) y h*g(t,x,y)
0 1 0.00 0 -0.25
1/4 1.0 -0.062 -0.25 -0.23
1/2 0.94 -0.12 -0.48 -0.17
3/4 0.82 -0.16 -0.66 -0.081
1 0.65 -0.18 -0.74 0.022
t,x,y = PolynomialRing(RealField(10),3,"txy").gens() f = y; g = -x - y * t eulers_method_2x2(f,g, 0, 1, 0, 1/4, 1)
Portanto,
Podemos também representar em um gráfico os pontos eulers_method_2x2_plot
fará isso; para usá-la, precisamos definir
funções f e g que recebam um argumento com três coordenadas (t,
x, y).
sage: f = lambda z: z[2] # f(t,x,y) = y
sage: g = lambda z: -sin(z[1]) # g(t,x,y) = -sin(x)
sage: P = eulers_method_2x2_plot(f,g, 0.0, 0.75, 0.0, 0.1, 1.0)
>>> from sage.all import *
>>> f = lambda z: z[Integer(2)] # f(t,x,y) = y
>>> g = lambda z: -sin(z[Integer(1)]) # g(t,x,y) = -sin(x)
>>> P = eulers_method_2x2_plot(f,g, RealNumber('0.0'), RealNumber('0.75'), RealNumber('0.0'), RealNumber('0.1'), RealNumber('1.0'))
f = lambda z: z[2] # f(t,x,y) = y g = lambda z: -sin(z[1]) # g(t,x,y) = -sin(x) P = eulers_method_2x2_plot(f,g, 0.0, 0.75, 0.0, 0.1, 1.0)
A esta altura, P
armazena dois gráficos: P[0]
, o gráfico de
x versus t, e P[1]
, o gráfico de y versus t. Podemos
visualizar os dois gráficos da seguinte forma:
sage: show(P[0] + P[1])
>>> from sage.all import *
>>> show(P[Integer(0)] + P[Integer(1)])
show(P[0] + P[1])
(Para mais sobre gráficos, veja Gráficos.)
Funções Especiais¶
Diversos polinômios ortogonais e funções especiais estão implementadas, usando tanto o PARI [GP] como o Maxima [Max]. Isso está documentado nas seções apropriadas (“Orthogonal polynomials” and “Special functions”, respectivamente) do manual de referência do Sage (em inglês).
sage: x = polygen(QQ, 'x')
sage: chebyshev_U(2,x)
4*x^2 - 1
sage: bessel_I(1,1).n(250)
0.56515910399248502720769602760986330732889962162109200948029448947925564096
sage: bessel_I(1,1).n()
0.56515910399248...
sage: bessel_I(2,1.1).n() # last few digits are random
0.16708949925104...
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> chebyshev_U(Integer(2),x)
4*x^2 - 1
>>> bessel_I(Integer(1),Integer(1)).n(Integer(250))
0.56515910399248502720769602760986330732889962162109200948029448947925564096
>>> bessel_I(Integer(1),Integer(1)).n()
0.56515910399248...
>>> bessel_I(Integer(2),RealNumber('1.1')).n() # last few digits are random
0.16708949925104...
x = polygen(QQ, 'x') chebyshev_U(2,x) bessel_I(1,1).n(250) bessel_I(1,1).n() bessel_I(2,1.1).n() # last few digits are random
No momento, essas funções estão disponíveis na interface do Sage apenas para uso numérico. Para uso simbólico, use a interface do Maxima diretamente, como no seguinte exemplo:
sage: maxima.eval("f:bessel_y(v, w)")
'bessel_y(v,w)'
sage: maxima.eval("diff(f,w)")
'(bessel_y(v-1,w)-bessel_y(v+1,w))/2'
>>> from sage.all import *
>>> maxima.eval("f:bessel_y(v, w)")
'bessel_y(v,w)'
>>> maxima.eval("diff(f,w)")
'(bessel_y(v-1,w)-bessel_y(v+1,w))/2'
maxima.eval("f:bessel_y(v, w)") maxima.eval("diff(f,w)")