O teorema fundamental do cálculo é um teorema que conecta o conceito de diferenciação de uma função (cálculo do gradiente) com o conceito de integração de uma função (cálculo da área sob a curva). As duas operações são inversas uma da outra, exceto por um valor constante que depende de onde se começa a calcular a área.
A primeira parte do teorema, às vezes chamada de primeiro teorema fundamental do cálculo, afirma que uma das antiderivadas (também conhecida como integral indefinida), digamos F, de alguma função f pode ser obtida como a integral de f com um limite variável de integração. Isso implica na existência de antiderivadas para funções contínuas.
Por outro lado, a segunda parte do teorema, às vezes chamada de segundo teorema fundamental do cálculo, afirma que a integral de uma função f em algum intervalo pode ser calculada usando qualquer um, digamos F, de suas infinitas antiderivadas. Esta parte do teorema tem aplicações práticas chave, porque encontrar explicitamente a antiderivada de uma função por integração simbólica evita integração numérica para calcular integrais.
O teorema fundamental do cálculo relaciona diferenciação e integração, mostrando que essas duas operações são essencialmente inversas uma da outra. Antes da descoberta desse teorema, não era reconhecido que essas duas operações estavam relacionadas. Os matemáticos da Grécia Antiga sabiam como calcular a área por meio de infinitesimais, uma operação que agora chamaríamos de integração.
A animação a seguir apresenta a relação entre a derivada e integral:
A primeira declaração publicada e prova de uma forma rudimentar do teorema fundamental, de caráter fortemente geométrico, foi por James Gregory (1638-1675). Isaac Barrow (1630-1677) provou uma versão mais generalizada do teorema, enquanto seu aluno Isaac Newton (1642-1727) completou o desenvolvimento da teoria matemática circundante. Gottfried Leibniz (1646–1716) sistematizou o conhecimento em um cálculo para quantidades infinitesimais e introduziu a notação usada hoje.
Com esta introdução, vamos agora utilizar um Sistema Algébrico Computacional para melhorar a nossa intuição a respeito deste teorema.
Um Sistema Algébrico Computacional é um programa que permite a computação de expressões matemáticas. Em contraste à uma simples calculadora, o SAC resolve os problemas não de forma numérica, mas usando expressões simbólicas, como variáveis, funções, polinômios e matrizes.
Todo SAC tem essencialmente a mesma funcionalidade. Isso significa que se você entender como um deles funciona, você será capaz de usar todos os outros também. Sistemas comerciais conhecidos incluem Maple, MATLAB e Mathematica, existem também os gratuitos e livres, podemos citar, por exemplo: Octave, Magma e SymPy (ao qual abordaremos neste notebook).
Em um SAC Simbólico, números e operações são expressados simbolicamente, sendo assim as respostas obtidas são exatas. Por exemplo o número $\sqrt{2}$ é representado em SymPy como o objeto Pow(2, 1/2)
. Em um Sistema Algébrico Numérico como Octave o número $\sqrt{2}$ é representado como a aproximação 1.41421356237310 (ponto flutuante). Para muitos casos está certo, mas essas aproximações podem nos trazer problemas: float(sqrt(2)) * float(sqrt(2)) = 2.00000000000000004 ≠ 2
. Pelo fato de SymPy usar a representação exata, tais problemas não aparecerão! Pow(2,1/2) * Pow(2,1/2) = 2
.
Nós podemos utilizar SymPy diretamente do interpretador Python, além disso, ele integra muito bem com o Jupyter-Notebook.
Para usá-lo, entretanto, precisamos primeiro importá-lo.
Também é interessante inicializarmos o modo pretty print, onde SymPy pode imprimir nossa saída usando caracteres Unicode.
from sympy import *
init_printing()
Dessa forma importamos todos os métodos e variáveis de SymPy. Agora vamos começar aprendendo sobre os objetos e operações básicas de SymPy. Por exemplos, nós vamos aprender o que significa resolver uma equação, expandir uma expressão e fatorar polinômios.
Mas antes, vejamos algumas particularidades, por exemplo, a respeito do número 1/7:
1/7
A representação do ponto flutuante á apenas válida para no máximo 16 decimais, pois 1/7 é infinitamente longo.
Para obter uma representação exata nós podemos simplificar a expressão usando a função S():
S("1/7")
Assim como na vida real, quando trabalhamos em matemática ou física, é melhor que possamos trabalhar simbolicamente até o fim, antes de computarmos uma resposta numérica, para assim evitarmos erros de arredondamento.
Em SymPy é interessante usarmos os objetos SymPy assim que possível e então obter uma aproximação numérica do objeto SymPy final, como um ponto flutuante, para isso utilizamos o método evalf().
Por exemplo, vamos considerar $\pi$ que já vem construído em SymPy como pi:
pi
Se quisermos avaliá-lo numericamente, podemos chamar o método evalf():
pi.evalf()
Também podemos utilizar o método global do SymPy n() para obtermos valores numéricos.
Ao fornecermos um valor inteiro como argumento, nós podemos facilmente alterar o número de dígitos de precisão que as aproximações devem retornar, por exemplo:
pi.n(120)
Para definirmos um símbolo em SymPy é necessário utilizarmos o método Symbol(), assim poderemos trabalhar com ele em expressões:
x = Symbol("x")
x
Com o símbolo $x$ definido, agora podemos usá-lo para construir expressões:
2*x + 2
O nome x é definido como um símbolo, sendo assim SymPy sabe que $2x + 2$ é uma expressão.
Também podemos criar uma lista de símbolos com a seguinte notação:
x0, x1, x2, x3 = symbols('x0:4')
Nós podemos basicamente nomear nossas variáveis da maneira que desejarmos, mas é interessante evitarmos sobrescrever nomes construídos em Sympy, como por exemplo Q, C, O, S, I e E.
Por exemplo, I é a unidade imaginária de um número, E é a base do logaritmo natural.
O underscore _
é uma variável especial que contém o resultado do último valor impresso. É análogo ao botão ans em muitas calculadoras, em outros Sistemas Algébricos Computacionais é normalmente utilizado o %:
3+3
_*10
Podemos definir uma expressão com a combinação de símbolos e operações matemáticas básicas e outras funções:
expressão = 2*x + 3*x - sin(x) - 3*x + 42
expressão
A função sympify (não deve ser confundida com simplify) pode ser usada para converter strings em expressões SymPy:
sympify('2*x + 3*x - sin(x) - 3*x + 42')
Outra operação matemática muito comum em expressões é mostrada a seguir.
O método factor() computa a fatoração de uma expressão especificada:
factor(x**2-2*x-8)
O método expand() é a operação "inversa" do factor() e executa a expansão de uma expressão:
expand((x-4)*(x+2))
Com o método collect() nós podemos coletar os termos para diferentes potências de uma dada variável (neste exemplo utilizamos $x$) para uma expressão:
a, b = symbols("a b")
collect(x**2 + x*b + a*x + a*b, x)
Para substituirmos um determinado valor em uma expressão, nós chamamos o método subs(), passando a ele um dicionário ({chave:valor}
).
Vamos então definir uma nova expressão contendo as funções seno e cosseno:
y = Symbol("y")
expr = sin(x) + cos(y)
expr
Usamos então o método subs para substituir $x$ por $1$ e $y$ por $2$:
expr.subs({x:1, y:2})
Finalmente, podemos usar n() para obter um resultado numérico:
expr.subs({x:1, y:2}).n()
A função solve talvez seja a ferramenta mais poderosa do SymPy, ela pode resolver praticamente qualquer equação. A função recebe dois argumentos: solve(expr, var).
Por exemplo, vamos resolver a equação quadrática:
$x^2 + 2x - 8 = 0$
solve(x**2+2*x-8,x)
O resultado é uma lista de soluções para $x$ que satisfaz a equação acima. A melhor parte do solve() é que ele também funciona com expressões simbólicas.
Por exemplo, vamos buscar a solução de:
$ax^2 + bx + c = 0$
a, b, c = symbols('a b c')
solve(a*x**2+b*x+c, x)
Utilizamos os símbolos a, b e c para resolver a equação. Você deve reconhecer a solução da fórmula quadrática:
$$ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} \quad \text{quando} \quad ax^2 + bx + c = 0 $$Para resolvermos um sistema de equações, nós podemos alimentar a função solve com uma lista de equações e uma lista de termos desconhecidos, que assim ele deve resolver a equação.
Vamos tentar resolver para $x$ e $y$ o sistema de equações a seguir:
$$x + y = 3$$$$3x -2y = 0$$solve([x+y-3, 3*x-2*y],[x,y])
Por padrão, SymPy não combinará ou separará expressões racionais.
É necessário utilizarmos o método together para calcular simbolicamente a adição de frações:
a, b, c, d = symbols("a b c d")
a/b + c/d
together(a/b+c/d)
Se você tiver uma expressão racional e desejar dividir o numerador pelo denominador, use o método apart:
apart((x**2+x+4)/(x+2))
Vamos agora definir um polinômio $P$ com raízes em $x = 1$, $x = 2$ e $x = 3$:
P = (x-1)*(x-2)*(x-3)
P
Para obtermos a versão expandida do polinômio, chamaremos o método expand:
P.expand()
Se nós começarmos com a forma expandida $P(x) = x³ - 6x² + 11x - 6$ nós podemos obter as raízes utilizando os métodos factor ou simplify:
P.factor()
A função simplify pode ser utilizada em qualquer expressão para simplificá-la:
P.simplify()
Lembre que as raízes do polinômio $P(x)$ são definidas como soluções para a equação $P(x) = 0$.
Nós podemos usar a função solve para encontrarmos as raízes do polinômio:
roots = solve(P,x)
roots
Podemos então checar se $P$ é igual $(x-1)(x-2)(x-3)$:
simplify(P - (x-roots[0])*(x-roots[1])*(x-roots[2]))
As funções trigonométricas como seno (sin) e cosseno (cos) recebem inputs em radianos.
Para chamarmos elas usando argumentos em graus é necessário o fator de conversão $\frac{{\pi}}{{180}}$ ou utilizar numpy.radians ou numpy.deg2rad da biblioteca NumPy.
SymPy está ciente de diversas identidades trigonométricas:
sin(x) == cos(x-pi/2)
True
simplify(sin(x)*cos(y) + cos(x)*sin(y))
e = 2*sin(x)**2 + 2*cos(x)**2
trigsimp(e)
simplify(sin(x)**4 -2* cos(x)**2* sin (x)**2+ cos (x)**4)
expand_trig(sin(2*x))
Cálculo, originalmente chamado de cálculo infinitesimal ou "o cálculo dos infinitesimais", é o estudo matemático da mudança contínua, da mesma forma que a geometria é o estudo da forma e a álgebra é o estudo das generalizações das operações aritméticas.
Ele possui dois ramos principais, cálculo diferencial e cálculo integral; o primeiro diz respeito às taxas instantâneas de mudança e às inclinações das curvas, enquanto o cálculo integral diz respeito ao acúmulo de quantidades e áreas sob ou entre as curvas. Esses dois ramos estão relacionados entre si pelo teorema fundamental do cálculo e fazem uso das noções fundamentais de convergência de sequências infinitas e séries infinitas até um limite bem definido.
Aqui nós iremos aprender os métodos de SymPy para calcularmos limites, derivadas, integrais e somatórios.
O símbolo para o infinito ($\infty$) em SymPy é denotado como dois o's em lowercase. SymPy sabe como tratar o infinito corretamente em expressões.
Por exemplo:
oo
oo + 1
5000 < oo
1/oo
oo > 9999999999999999
Com limites nós podemos descrever, com precisão matemática, infinitas grandes quantidades, infinitas pequenas quantidades e procedimentos com infinitos passos.
Por exemplo, o número $e$ é definido como o limite:
\begin{equation} e \equiv \lim_{n\to\infty}\left(1 + \frac{{1}}{{n}}\right)^n\end{equation}SymPy nos permite facilmente calcular ele:
n = Symbol('n')
limit((1+1/n)**n, n, oo)
E com o método evalf() podemos obter um resultado numérico:
E.evalf()
Limites também são úteis para descrever comportamento assintótico da função.
Para isso, considere a seguinte função:
\begin{equation}f(x)=\frac1x\end{equation}limit(1/x, x, 0, dir='+')
limit(1/x, x, 0, dir='-')
limit(1/x, x, oo)
A derivada de uma função de uma variável real mede a sensibilidade à mudança do valor da função (valor de saída) em relação a uma mudança em seu argumento (valor de entrada). As derivadas são uma ferramenta fundamental de cálculo. Por exemplo, a derivada da posição de um objeto em movimento em relação ao tempo é a velocidade do objeto: mede a rapidez com que a posição do objeto muda quando o tempo avança.
Uma função de uma variável real $y = f(x)$ é diferenciável em um ponto $a$ de seu domínio, se seu domínio contém um intervalo aberto $I$ contendo $a$, e o limite existe.
$$L = \lim_{h\to 0}{\frac {f(a+h) - f(a)}{h}}$$Isso significa que, para cada número real positivo $\varepsilon$, existe um número real positivo $\delta$ tal que, para cada $h$ tal que $|h| < \delta$ e $h \neq 0$, então $f(a + h)$ é definido:
$$|L - {\frac{f(a + h) - f(a)}{h}}| < \varepsilon$$Onde as barras verticais denotam o valor absoluto. Se a função $f$ é diferenciável em $a$, isto é, se o limite $L$ existe, então este limite é chamado de derivada de $f$ em $a$.
A função derivada é denotada normalmente por: \begin{equation}f'(x) , \frac{{d}}{{dx}}f(x) , \frac{{df}}{{dx}} , \frac{{dy}}{{dx}} \end{equation}
Lembre que a derivada descreve a taxa de variação de uma função $f(x)$.
O método diff do SymPy computa a derivada de uma dada expressão:
diff(x**3, x)
O método diff está ciente da regra do produto:
\begin{equation}[f(x)g(x)]' = f'(x)g(x) + f(x)g'(x)\end{equation}diff(x**2*sin(x), x)
E também da regra da cadeia:
\begin{equation}f(g(x))' = f'(g(x))g'(x)\end{equation}diff(sin(x**2), x)
e, por fim, a regra do quociente:
\begin{equation}\left(\frac{{f(x)}}{{g(x)}}\right)' = \frac{{f'(x)g(x) - f(x)g'(x)}}{{g(x)²}}\end{equation}diff(x**2/sin(x), x)
Uma equação diferencial é uma equação que relaciona alguma função desconhecida $f(x)$ com sua derivada.
Como exemplo vamos considerar $f'(x) = f(x)$ ou a expressão equivalente $f(x) - f'(x) = 0$
Para resolvermos esse problema aplicaremos o método dsolve:
z = symbols('z')
f = symbols('f', cls=Function)
dsolve(f(x) - diff(f(x),x), f(x))
Uma integral atribui números a funções de uma forma que descreve deslocamento, área, volume e outros conceitos que surgem pela combinação de dados infinitesimais. O processo de encontrar integrais é chamado de integração. Junto com a diferenciação, a integração é uma operação fundamental e essencial do cálculo, e serve como uma ferramenta para resolver problemas em matemática e física envolvendo a área de uma forma arbitrária, o comprimento de uma curva e o volume de um sólido, entre outros.
A integral de uma função $f(x)$ corresponde à computação da área abaixo do gráfico de $f(x)$.
A área abaixo de $f(x)$ entre os pontos $x = a$ e $x = b$ é denotada como:
\begin{equation}A(a,b) = \int_{a}^{b} f(x)dx\end{equation}A função integral $F$ corresponde ao cálculo da área como função do limite superior da integração:
\begin{equation}F(c) = \int_{0}^{c} f(x)dx\end{equation}A área debaixo $f(x)$ entre $x = a$ e $x = b$ é dada:
\begin{equation}A(a,b) = \int_{a}^{b} f(x)dx = F(b) - F(a)\end{equation}Em SymPy nós usamos integrate(f, x) para obter a função integral $F(x)$ de qualquer dada função $f(x)$:
integrate(x**3, x)
integrate(sin(x), x)
integrate(ln(x), x)
Isso é conhecido como integral indefinida, uma vez que não foi especificado o limite da integração.
Em contraste, uma integral definida computa a área debaixo de $f(x)$ entre $x = a$ e $x = b$:
integrate(x**3, (x, 0, 1))
Nós podemos obter a mesma área, primeiro calculando a integral indefinida:
\begin{equation}F(c) = \int_{0}^{c} f(x)dx\end{equation}E então usar:
\begin{equation}A(a,b) = \int_{a}^{b} f(x)dx = F(b) - F(a)\end{equation}F = integrate(x**3, x)
F.subs({x: 1}) - F.subs({x: 0})
A integral é a operação inversa da derivada. Se você executar a operação integral seguidamente da operação derivada em uma função, você obterá a mesma função:
\begin{equation}\left(\frac{{d}}{{dx}} \circ \int_ .dx \right)f(x) \equiv \frac{{d}}{{dx}} \int_{c}^{x} f(u)du \equiv f(x)\end{equation}Por exemplo:
f = x**2
F = integrate(f,x)
F
diff(F,x)
Alternativamente, se computarmos a derivada de uma função seguida de sua integral nós iremos obter a função original $f(x)$ e mais uma constante:
\begin{equation}\left( \int_ .dx \circ \frac{{d}}{{dx}} \right)f(x) \equiv \int_{c}^{x} f'(u)du = f(x) + C\end{equation}Por exemplo:
f = x**2
df = diff(f, x)
df
integrate(df, x)
O Teorema Fundamental do Cálculo é importante porque ele nos diz como resolver equações diferenciais. Se nós tivermos que resolver para $f(x)$ na equação diferencial:
\begin{equation}\frac{{d}}{{dx}}f(x) = g(x)\end{equation}Nós podemos obter a integral em ambos os lados da equação para obtermos a resposta:
\begin{equation}f(x) = \int_ . g(x)dx + C\end{equation}Sequências são funções que recebem inteiros (números inteiros) como input ao invés de inputs contínuos (números reais). Uma sequência é denotada como $a_n$ para diferenciar da notação da função $a(n)$.
Nós definimos uma sequência especificando uma expressão para seu $n$ termo:
n = Symbol('n')
a_n = 1/n
a_n
b_n = 1/factorial(n)
b_n
Usando as list comprehensions em Python, nós podemos gerar a sequência para alguns gamas de índices:
[a_n.subs({n:i}) for i in range(0,8)]
[b_n.subs({n:i}) for i in range(0,8)]
Ambos $a_n = \frac{{1}}{{n}}$ e $b_n = \frac{{1}}{{n!}}$ convergem para 0 como: $n \rightarrow \infty$.
Podemos confirmar com o método limit():
limit(a_n, n, oo)
limit(b_n, n, oo)
Vamos supor que nos é dado uma sequência $a_n$ e nós desejamos computar a soma de todos os valores na sequência:
\begin{equation}\sum_{n}^{\infty} = a_n\end{equation}Séries são somas de sequências. Somando os valores da sequência $a_n : \mathbb{N} \rightarrow \mathbb{R}$ é análogo a obter a integral de uma função $f : \mathbb{R} \rightarrow \mathbb{R}$
O método análogo para integrar para séries é chamado summation::
a_n = 1/n
summation(a_n, [n, 1, oo])
b_n = 1/factorial(n)
summation(b_n, [n, 0, oo])
O coeficiente na séries de potência de uma função depende no valor de derivadas de ordem maior da função. A equação para o termo $n$ na série de Taylor de $f(x)$ expandida em $x = c$ é:
\begin{equation}a_n(x) = \frac{{f^n(c)}}{{n!}}(x - c)^n\end{equation}Onde $f^n(x)$ é o valor da derivada $n$ de $f(x)$ avaliada em $x = c$. Uma expansão de série de Taylor em $x = 0$ é chamada de série de Maclaurin.
Não apenas nós podemos usar séries para aproximarmos números, nós podemos utilizar elas para aproximar funções!
Uma série de potência é uma série no qual os termos contém diferentes potências da variável $x$. Por exemplo, a série de potência da função:
\begin{equation}exp(x) = e^x\end{equation}\begin{equation}exp(x) \equiv 1 + x + \frac{{x^2}}{{2}} + \frac{{x^3}}{{3!}} + \frac{{x^4}}{{4!}} + \frac{{x^5}}{{5!}} + ... = \sum_{n=0}^{\infty} \frac{{x^n}}{{n!}} \end{equation}exp_xn = x**n/factorial(n)
exp_xn
summation = exp_xn.subs({x:5, n:2})
summation.evalf()
Em SymPy as séries de função nos possibilitam uma forma fácil de obter séries de qualquer função.
Chamando series(expr, var, ar, nmax) irá calcular a expansão da série da expressão próxima a var=at
à potência de nmax
.
Por exemplo:
series(sin(x), x, 0, 8)
series(cos(x), x, 0, 8)
series(sinh(x), x, 0, 8)
series(cosh(x), x, 0, 8)
Se uma função não estiver definida em $x = 0$, nós podemos expandir ela em um valor diferente de $x$.
Por exemplo, a série de potência de $ln(x)$ expandida em $x = 1$ é:
series(ln(x), x, 1, 6)
Para eliminarmos os termos $(x - 1)$ e obtermos um resultado familiar para a série de Taylor nós podemos utilizar a seguinte técnica:
Em vez de expandir $ln(x)$ em $x = 1$, nós obteremos uma expressão mais legível expandindo $ln(x + 1)$ em $x = 0$.
series(ln(x+1), x, 0, 6)