Conteúdo restrito à equipe do trabalho A Derivada na Computação. Informe a senha combinada pelo grupo.
Explicação detalhada de cada assunto da apresentação "A Derivada na Computação" — use como leitura antes do ensaio ou para responder perguntas da banca com mais profundidade do que cabe em um slide.
Fora do contexto puramente matemático, a derivada responde a uma pergunta muito concreta: "quando eu mexo um pouquinho aqui, quanto muda ali?" É a medida da sensibilidade de uma saída em relação a uma entrada — a taxa de variação instantânea.
Essa ideia aparece em computação sob três papéis recorrentes, que servem de fio condutor para todo o restante deste material: otimização (em que direção ajustar para melhorar?), detecção de variação (onde algo mudou bruscamente?) e previsão e controle (para onde isso está indo?).
Um detalhe essencial: o computador quase nunca calcula a derivada "no papel". Ela é obtida de forma discreta — comparando valores vizinhos — ou de forma automática, por bibliotecas que a derivam em tempo de execução. A definição clássica usa o limite:
Como não há como programar um limite, usa-se a diferença finita com um passo h pequeno e finito:
A fórmula acima parece abstrata, mas todo mundo já a usou. Se um carro percorre 100 km em 2 horas, a velocidade média é (100 − 0)/(2 − 0) = 50 km/h — variação da saída dividida pela variação da entrada. É exatamente (f(x+h) − f(x)) / h.
A derivada é o que acontece quando encolhemos esse intervalo até virar um instante: sai a velocidade média e entra a velocidade instantânea, a do velocímetro. Geometricamente, a reta que corta a curva em dois pontos (secante) vai se aproximando da reta que a toca em um só (tangente). A derivada é a inclinação dessa tangente.
O ponto central para computação é que o computador nunca chega ao instante — ele para no intervalo pequeno. Toda derivada em código é, no fundo, uma velocidade média calculada num intervalo curto o bastante para o erro não importar.
A diferença é onde se olha. A progressiva compara o ponto atual com o próximo — é o que se usa quando só há o passado e o presente, como em um sensor lendo em tempo real (não dá para consultar uma leitura que ainda não aconteceu). A central compara o ponto anterior com o posterior, ficando simétrica em torno do ponto de interesse; essa simetria faz os erros dos dois lados se cancelarem parcialmente, e é isso que a torna mais precisa.
Testando com f(x) = x³ no ponto x = 2 (valor exato: f'(2) = 12), reduzir o passo por um fator de 10 derruba o erro da diferença progressiva por 10× e o da central por 100× — respectivamente precisão de 1ª e 2ª ordem. Traduzindo o que "ordem" significa aqui: na progressiva, dez vezes mais esforço compra um dígito a mais de precisão; na central, compra dois. É por isso que bibliotecas de processamento de sinais e de imagem preferem a forma central sempre que dispõem do valor anterior e do posterior — e é também a razão de a máscara de Sobel ser simétrica, como se verá adiante.
Reduzir h indefinidamente não melhora o resultado: abaixo de aproximadamente 10⁻⁸, a subtração de dois números quase idênticos em ponto flutuante provoca cancelamento catastrófico e o erro volta a crescer. Existe um passo ótimo — determiná-lo é um problema clássico de análise numérica.
Treinar um modelo significa encontrar os valores de milhões de parâmetros internos que produzem o menor erro possível. O erro é representado por uma função de perda — imagine uma superfície montanhosa em que a altitude é o tamanho do erro. O algoritmo é "cego": não enxerga a superfície inteira, só sente a inclinação do terreno sob os pés. Essa inclinação é a derivada.
O método que usa essa informação é o gradiente descendente:
onde w é o parâmetro, L a função de perda e α a taxa de aprendizado — o tamanho do passo. Passo grande demais faz o modelo pular o vale e oscilar (ou divergir); passo pequeno demais torna o treinamento lento.
Seja L(w) = (w−3)², cujo mínimo está em w = 3. A derivada é L'(w) = 2(w−3). Partindo de w₀ = 0 com α = 0,1:
| iteração | w | L'(w) |
|---|---|---|
| 0 | 0,000 | −6,000 |
| 1 | 0,600 | −4,800 |
| 2 | 1,080 | −3,840 |
| 3 | 1,464 | −3,072 |
| 4 | 1,771 | −2,458 |
Note que os passos encolhem sozinhos conforme a derivada diminui — perto do mínimo, o ajuste é naturalmente mais fino, sem nenhuma lógica extra. A própria derivada regula isso.
Esse gráfico costuma ser mal interpretado, porque parece o gráfico de uma função comum — mas o eixo horizontal não é o tempo. Vale destrinchar cada elemento:
| O que aparece | O que significa |
|---|---|
| Eixo horizontal (w) | O valor do parâmetro que o modelo está tentando acertar. Não é tempo: é o "botão" que o treinamento gira. |
| Eixo vertical (L(w)) | O erro que esse valor de w produz. Quanto mais alto, pior o modelo. |
| Curva verde | Todos os erros possíveis, para todo w. Na vida real ela é desconhecida e tem milhões de dimensões — aqui é desenhada só para nós enxergarmos o que o algoritmo não enxerga. |
| Tracejado vertical | A resposta certa (w = 3), o fundo do vale. É para lá que o treinamento deveria ir. |
| Bolinha branca | O valor atual de w. Ela não "rola" pela curva: ela salta, e o tamanho do salto é α × derivada. |
| Traço vermelho | O histórico dos saltos já dados, com um ponto por iteração. |
A confusão mais comum é achar que a bolinha desliza pela curva como uma bola física. Ela não desliza: a cada iteração ela é teletransportada para um novo valor de w, calculado pela fórmula. O traço vermelho ligando dois pontos é só o registro do salto, não um caminho percorrido. É por isso que, com α alto, o traço atravessa o vale em linha reta: a bolinha passou por cima do mínimo, sem nunca visitá-lo.
Esse comportamento não é aleatório nem aproximado — ele tem uma fórmula fechada, e vale a pena conhecê-la porque explica todos os regimes do gráfico de uma vez. Partindo da atualização com L'(w) = 2(w−3):
Chamando de erro a distância até o alvo, e = w − 3, e subtraindo 3 dos dois lados:
Ou seja: a cada passo o erro é simplesmente multiplicado pelo número (1 − 2α). Todo o resto decorre disso. Se esse fator tem módulo menor que 1, o erro encolhe e o método converge; se tem módulo maior que 1, o erro cresce e o método diverge; se é negativo, o erro troca de sinal a cada passo — que é exatamente a bolinha pulando de um lado do vale para o outro.
| α | fator (1 − 2α) | o que se vê na tela |
|---|---|---|
| 0,10 | +0,80 | Desce sempre pelo mesmo lado, em passos cada vez menores. Converge suave. |
| 0,50 | 0,00 | Acerta o mínimo em um único passo — o erro é multiplicado por zero. |
| 0,80 | −0,60 | Converge, mas atravessando o vale a cada passo (zigue-zague que vai apertando). |
| 1,00 | −1,00 | Fronteira exata: pula eternamente entre w = 0 e w = 6, sempre na mesma altura. Nunca converge nem diverge. |
| 1,20 | −1,40 | Diverge: o zigue-zague abre cada vez mais até a bolinha sair da tela. |
O caso α = 0,50 costuma surpreender — parece "bom demais". Ele acontece porque a parábola é simétrica e a derivada no ponto inicial aponta exatamente para o dobro da distância até o mínimo; meio passo dessa direção cai em cima do alvo. É uma coincidência desta função específica, não uma regra geral: em uma função de perda real, com milhões de parâmetros, não existe α que resolva tudo em um passo.
O caso α = 1,00 é o mais instrutivo para a apresentação, porque é o limite exato: o erro é multiplicado por −1 a cada passo, isto é, troca de sinal mas mantém o tamanho. A bolinha fica presa em um vaivém perpétuo entre 0 e 6, sempre à mesma altura na curva. Não é um bug da demonstração — é o comportamento matematicamente correto na fronteira da estabilidade.
O valor α = 1 não foi escolhido a dedo: ele é o caso particular da regra geral de estabilidade do gradiente descendente, α < 2/L'', aplicada a esta perda, cuja segunda derivada é constante e vale L'' = 2 — logo o limite é 2/2 = 1. Uma curva de perda mais "fechada" (L'' maior) exige α menor; é essa a razão de, na prática, se ajustar a taxa de aprendizado por tentativa e erro: ninguém conhece o L'' de uma rede neural real.
Uma consequência prática que vale citar na banca: divergir não é o mesmo que aprender devagar. Um α pequeno demais custa tempo de treinamento; um α grande demais não custa tempo — ele destrói o treinamento, e o erro cresce sem limite até virar NaN. Por isso a prática de começar com uma taxa conservadora e reduzi-la ao longo do treinamento (learning rate schedule) é o padrão em qualquer framework moderno.
Uma rede neural profunda tem dezenas de camadas empilhadas. Para saber quanto um parâmetro da primeira camada contribuiu para o erro medido na última, é preciso propagar a responsabilidade de trás para frente, camada por camada. O algoritmo que faz isso — o backpropagation, publicado em 1986 — é, na prática, a aplicação sistemática da regra da cadeia de derivadas.
Com z = w·x + b (soma ponderada), a = σ(z) (ativação) e L a perda final:
A regra da cadeia responde: se A afeta B, e B afeta C, quanto A afeta C? Resposta: multiplicando os dois efeitos. Se um aumento de 1% no preço reduz as vendas em 3%, e cada venda perdida custa R$ 2 de lucro, o efeito do preço sobre o lucro é o produto dessas duas sensibilidades.
Numa rede neural a cadeia é a mesma, só que mais longa: o peso w afeta a soma z, que afeta a ativação a, que afeta a perda L. Para saber quanto w afetou L, multiplica-se o efeito de cada elo:
Cada fator é calculado localmente por sua camada — nenhuma camada precisa saber o que as outras fazem, só derivar a própria operação. É essa localidade que torna o algoritmo viável: uma rede com bilhões de parâmetros nunca monta a expressão inteira, ela só multiplica elos vizinhos. Em uma rede de n camadas, o gradiente da primeira camada é um produto de n derivadas encadeadas.
E daí vem o alerta que a próxima seção desenvolve: se cada elo multiplica por um número menor que 1, o produto de muitos elos tende a zero. A regra da cadeia é ao mesmo tempo o que faz o aprendizado profundo funcionar e o que quase o impediu de funcionar.
O material implementa, sem nenhuma biblioteca, uma rede 2-2-1 que aprende a função XOR — problema que um modelo linear não resolve. As três linhas centrais do algoritmo são literalmente a regra da cadeia:
dL_da = 2 * (a_saida - alvo) # derivada da perda
da_dz = derivada_sigmoide(a_saida) # derivada da ativação
delta_saida = dL_da * da_dz # regra da cadeiaRetirar a linha da_dz — ignorar a derivada da ativação — faz a rede parar de aprender. Não há "inteligência" além disso: o aprendizado é a aplicação repetida de derivadas parciais. Após 20 mil épocas, a rede reproduz XOR com erro menor que 1%.
Trocando a semente aleatória de 1 para 42, a mesma rede falha — o erro estaciona em ~0,53. O gradiente descendente encontrou um mínimo local, um ponto onde a derivada é nula mas que não é a melhor solução. A derivada só enxerga a inclinação imediata, não o relevo inteiro; por isso técnicas como momentum e reinicializações múltiplas existem.
Um neurônio artificial faz duas coisas. Primeiro calcula uma soma ponderada das suas entradas: z = w₁x₁ + w₂x₂ + … + b. Essa parte é pura álgebra linear. Depois passa esse número por uma função de ativação, que decide o quanto o neurônio "dispara": a = f(z).
Sem essa segunda etapa a rede inteira seria inútil por um motivo puramente matemático: a composição de várias funções lineares continua sendo uma função linear. Empilhar cem camadas sem ativação produziria exatamente o mesmo poder de representação de uma única camada — nenhuma rede profunda conseguiria aprender nada que uma reta já não aprendesse. A função de ativação é o que introduz não-linearidade, e é por isso que ela existe.
A sigmoide comprime qualquer número real para o intervalo aberto (0, 1), desenhando um "S" achatado. Entradas muito negativas viram algo próximo de 0; muito positivas, próximo de 1; e o zero cai exatamente no meio, σ(0) = 0,5. Foi a ativação dominante até meados dos anos 2000, por três razões que faziam sentido na época: a saída parece uma probabilidade, a função é suave e derivável em todo ponto, e ela imita a ideia biológica de um neurônio que satura.
Sua derivada tem uma propriedade elegante: pode ser escrita em função da própria saída, σ'= σ(1−σ). Isso significa que, tendo calculado a ativação na passagem para frente, a derivada sai de graça na passagem para trás — uma economia relevante quando isso roda bilhões de vezes. Mas é justamente essa derivada que cria o problema:
| x | σ(x) | σ'(x) |
|---|---|---|
| 0 | 0,500 | 0,250 (máximo possível) |
| ±2 | 0,881 / 0,119 | 0,105 |
| ±4 | 0,982 / 0,018 | 0,018 |
| ±6 | 0,998 / 0,002 | 0,002 |
O melhor caso possível da derivada da sigmoide é 0,25, e ele ocorre em um único ponto (x = 0). Longe do centro a função satura: fica praticamente horizontal, a derivada despenca para quase zero, e o neurônio para de responder a mudanças. Como o gradiente descendente só se move proporcionalmente à derivada, um neurônio saturado efetivamente congela — mesmo que sua resposta esteja errada.
A ReLU (Rectified Linear Unit) é quase constrangedoramente simples: se a entrada é negativa, devolve zero; se é positiva, devolve ela mesma. No código, uma linha: max(0, x). E é exatamente essa simplicidade que resolve o problema — na região ativa (x > 0) sua derivada vale exatamente 1, e multiplicar por 1 não atenua nada.
Três ganhos práticos vêm junto: (1) não há exponencial para calcular, então ela é muito mais barata que a sigmoide; (2) como a saída é exatamente zero para entradas negativas, boa parte dos neurônios fica inativa a cada passagem, produzindo representações esparsas que costumam generalizar melhor; (3) a função não satura para valores positivos — pode crescer indefinidamente, e o gradiente continua passando.
Ela tem um defeito próprio, que vale mencionar para não passar a impressão de bala de prata: como a derivada é zero para x < 0, um neurônio que passe a receber sempre entradas negativas nunca mais recebe gradiente e morre permanentemente — o problema do dying ReLU. É para isso que existem variantes como a Leaky ReLU, que usa uma inclinação pequena (0,01x em vez de 0) no lado negativo, mantendo um fio de gradiente vivo. Um detalhe matemático fino: a ReLU não é derivável em x = 0 exatamente; as bibliotecas simplesmente convencionam a derivada como 0 ou 1 nesse ponto, e como ele tem medida nula na prática, isso nunca causa problema real.
Agora as duas peças se juntam. Pela regra da cadeia (ver a seção anterior), o gradiente que chega à primeira camada é o produto das derivadas de todas as camadas acima dela. Multiplicar muitos números menores que 1 leva o resultado a zero exponencialmente rápido:
| camadas | sigmoide | ReLU |
|---|---|---|
| 1 | 2,500 × 10⁻¹ | 1,0 |
| 10 | 9,537 × 10⁻⁷ | 1,0 |
| 50 | 7,889 × 10⁻³¹ | 1,0 |
Com 50 camadas e sigmoide, o gradiente é da ordem de 10⁻³¹ — indistinguível de zero em ponto flutuante; o parâmetro nunca é atualizado. Esse é o problema do gradiente evanescente (vanishing gradient): não é que a rede aprenda devagar, é que as camadas iniciais literalmente param de aprender, enquanto as finais continuam ajustando. E como são justamente as primeiras camadas que aprendem as características mais básicas, a rede profunda acaba desempenhando pior que uma rasa — o oposto do que a intuição sugere.
Repare que a tabela usa o melhor caso da sigmoide (0,25 em todas as camadas). Na prática a maioria dos neurônios opera fora do centro, com derivadas na casa de 0,1 ou menos, e o colapso é ainda mais rápido. Com a ReLU o produto é 1 × 1 × … × 1 = 1: o gradiente atravessa a rede inteira sem atenuação nenhuma, por mais profunda que ela seja.
Este é talvez o exemplo mais forte do trabalho: por décadas acreditou-se que redes profundas eram inviáveis por falta de dados ou de poder computacional. A causa real era o valor máximo de uma derivada. Trocar σ por max(0, x) — uma mudança de uma linha, sem nenhuma teoria nova — foi um dos gatilhos diretos da revolução do deep learning. Uma decisão de engenharia de bilhões de dólares tomada inteiramente com base no comportamento de uma derivada.
Para efeito de contexto histórico, o mesmo raciocínio explica outras soluções conhecidas: as conexões residuais da ResNet criam um "atalho" pelo qual o gradiente passa com derivada 1, e os portões da LSTM foram desenhados para preservar gradiente ao longo do tempo em redes recorrentes. Todas atacam o mesmo inimigo — o produto de derivadas pequenas.
Ver no slide 8Frameworks como PyTorch, TensorFlow e JAX incorporam diferenciação automática (autodiff): enquanto o programador escreve as operações matemáticas, a biblioteca constrói em paralelo um grafo capaz de calcular as derivadas exatas de qualquer saída em relação a qualquer entrada.
Vale contrastar as alternativas, porque é uma pergunta natural de banca — "se já existe a diferença finita, para que autodiff?":
| método | como funciona | problema |
|---|---|---|
| Simbólico | Manipula a fórmula algebricamente, como se faria no papel (é o que o WolframAlpha faz). | A expressão explode de tamanho a cada derivação encadeada; inviável para milhões de parâmetros. |
| Diferença finita | Avalia a função duas vezes e divide pela distância. | Tem erro de aproximação, e exige duas avaliações por parâmetro — numa rede de 1 bilhão de parâmetros, 2 bilhões de execuções por passo. |
| Autodiff | Aplica a regra da cadeia operação por operação, durante a própria execução do código. | Nenhum dos dois: derivada exata (até o último bit) e custo proporcional ao da função original. |
É esse terceiro caminho que torna o treinamento moderno possível. Sem ele, cada arquitetura nova exigiria derivar a rede à mão e implementar o resultado sem errar um sinal — que era, literalmente, o trabalho de um pesquisador de redes neurais antes de 2015.
Uma das implementações usa números duais, da forma a + bε, com a propriedade ε² = 0. Avaliar uma função nesse número faz a expansão de Taylor truncar sozinha:
A parte real carrega o valor da função; a parte dual carrega a derivada — ambas obtidas em uma única passagem, sem erro de aproximação e sem manipulação simbólica. Derivando f(x) = x³ + 2x + sen(x) em x = 2 com uma implementação de ~40 linhas, o resultado bate exatamente com o valor analítico: derivada = 13,583853. É exatamente esse mecanismo — em escala, com suporte a tensores e GPU — que o autograd do PyTorch implementa.
O primeiro passo é o que costuma travar a compreensão: parar de pensar na imagem como um desenho e passar a pensar nela como uma função matemática. Uma foto em tons de cinza é, literalmente, uma tabela de números — cada pixel guarda um valor de 0 (preto) a 255 (branco). Ou seja, existe uma regra que recebe uma coordenada e devolve um número:
Uma vez aceito isso, a pergunta "onde está a borda desse objeto?" vira uma pergunta de cálculo: onde essa função muda depressa? Compare duas fatias horizontais de pixels vizinhos:
| região | valores dos pixels | variação entre vizinhos | interpretação |
|---|---|---|---|
| parede lisa | 120 · 121 · 120 · 122 · 121 · 120 | ≈ 0 | área uniforme, sem borda |
| quina de um objeto | 50 · 50 · 52 · 200 · 201 · 200 | +148 num único passo | borda: a função "pula" |
| sombra suave | 80 · 95 · 110 · 125 · 140 · 155 | +15 constante | gradiente suave, não é borda nítida |
É exatamente a mesma lógica da diferença finita da primeira seção deste material — só que aplicada no espaço em vez de no tempo. Como os pixels já são valores discretos e igualmente espaçados, o passo h vale 1 (um pixel), e a derivada discreta em x se reduz a uma subtração entre vizinhos:
Repare no detalhe: onde a imagem é uniforme a derivada é praticamente zero, e onde há borda ela dispara. Toda a detecção de contornos vive dessa frase — detectar bordas é detectar derivadas altas. O terceiro caso da tabela também é instrutivo: uma sombra suave tem derivada não nula, só que pequena e constante. É por isso que os detectores usam um limiar: sem ele, cada variação suave de iluminação viraria uma falsa borda.
Uma imagem é uma função de duas variáveis, então existem duas derivadas parciais: uma medindo a variação na horizontal e outra na vertical. Juntas formam o gradiente, um vetor que aponta para a direção de maior mudança de brilho:
Esse vetor carrega duas informações independentes, e ambas são usadas na prática. O módulo |∇I| diz quão forte é a borda — é ele que vira o brilho do pixel no mapa de bordas da demonstração. Já a direção (o ângulo arctan(G_y/G_x)) diz qual a orientação da borda, e é indispensável em algoritmos como o Canny, que a usa para afinar contornos grossos até a espessura de um pixel.
Uma consequência que ajuda a ler o resultado da demonstração: uma borda puramente vertical (como a divisa entre uma metade escura e uma clara) tem G_x grande e G_y igual a zero — a intensidade muda ao andar na horizontal, mas não ao subir ou descer. É por isso que a máscara "horizontal" detecta bordas verticais, e não o contrário, algo que costuma gerar confusão na hora de explicar.
Subtrair dois pixels vizinhos funciona, mas é extremamente sensível a ruído: um único pixel defeituoso cria uma borda falsa. O operador Sobel resolve isso olhando uma vizinhança 3×3 inteira e fazendo duas coisas ao mesmo tempo — deriva numa direção e suaviza na outra:
Lendo a máscara de G_x coluna por coluna: a coluna da esquerda entra com sinal negativo, a do meio é ignorada (zero) e a da direita entra positiva — é a subtração "direita menos esquerda" da derivada. O peso 2 na linha central dá mais importância ao pixel diretamente vizinho do que aos dois na diagonal, que é o efeito de suavização. Por isso o Sobel é bem mais robusto a ruído do que a subtração ingênua, mantendo o custo de apenas nove multiplicações por pixel.
Em uma vizinhança com borda vertical nítida (10 | 200), o cálculo manual dá G_x = 760 e G_y = 0 — borda de alta intensidade, puramente horizontal na direção de variação. O código do material reproduz exatamente esse valor, e o exercício 5 da lista repete a conta com outros números.
Outras técnicas derivam da mesma ideia: o Laplaciano usa a segunda derivada para localizar a borda no ponto exato em que a variação muda de sinal (zero-crossing); o Canny é o padrão da indústria; o fluxo óptico mede a derivada da imagem no tempo, não só no espaço, para estimar movimento entre quadros de vídeo.
Em produção, ninguém escreve os laços manualmente — a versão vetorizada usa NumPy/SciPy, e com OpenCV a operação inteira se reduz a cv2.Sobel(...). A derivada está tão consolidada como ferramenta que virou uma linha de API.
Toda superfície renderizada precisa saber "para onde ela aponta" (para calcular iluminação), e todo objeto em movimento precisa saber "para onde está indo". Ambas as informações são derivadas.
A ligação entre as duas é mais direta do que parece: a derivada sempre responde "para que lado isso está indo". Numa superfície, "para que lado" é a orientação — usada para decidir o quanto de luz o ponto recebe. Num objeto em movimento, é a direção do deslocamento. Mesmo conceito, perguntas diferentes.
Uma normal é a seta perpendicular à superfície em um ponto. Ela é o que permite calcular iluminação: uma face virada de frente para a lâmpada fica clara, uma de lado fica escura. Sem normais não há sombreamento — o objeto aparece como uma silhueta chapada.
Para uma superfície implícita F(x,y,z) = 0, o vetor normal é o gradiente de F. Numa esfera de raio r, F = x²+y²+z²−r², e ∇F = (2x, 2y, 2z) — que, normalizado, é exatamente o vetor radial. No modelo de iluminação de Lambert, o brilho de cada pixel é o produto escalar entre essa normal e a direção da luz: o ponto voltado para a luz recebe intensidade 1,0; o ponto lateral recebe 0,0.
A derivada da curva fornece o vetor tangente, que orienta câmeras, veículos e personagens ao longo de trajetórias suaves — é também o que garante continuidade visual entre trechos de curva emendados, e a razão pela qual arrastar as alças em um editor vetorial altera a inclinação inicial do traço.
Posição, velocidade e aceleração formam uma cadeia de derivadas: a velocidade é a derivada da posição (v = ds/dt) e a aceleração é a derivada da velocidade (a = dv/dt) — ou seja, a aceleração é a segunda derivada da posição. Um motor de física conhece a aceleração (a gravidade, por exemplo) e precisa do caminho inverso: descobrir a posição. Ele faz isso a cada quadro, acumulando:
Em nenhum momento o motor resolve uma equação de movimento fechada — ele apenas aplica repetidamente essas duas relações derivativas, e o comportamento físico realista (uma bola quicando, por exemplo) emerge disso. Esse laço de poucas linhas é o núcleo de qualquer motor de física, do Unity ao Unreal.
O Δt dessas fórmulas é o tempo entre dois quadros — e é aqui que a matemática encosta em algo que todo jogador já viu. Como o método aproxima cada intervalo por um pedacinho de reta, quanto maior o Δt, maior o erro acumulado. É a origem de bugs clássicos de física em jogos rodando com FPS baixo: com quadros muito espaçados, um objeto rápido pode "pular" para o outro lado de uma parede entre dois quadros, sem nunca ocupar uma posição dentro dela — a colisão simplesmente não é detectada. Por isso motores sérios rodam a física em passo fixo, independente da taxa de quadros da tela, e recorrem a detecção contínua de colisão para objetos velozes.
Ver no slide 11Funções que o programador invoca sem pensar — sqrt(), sin(), log() — não existem como instrução no processador; são calculadas por algoritmos que dependem de derivadas. O Newton-Raphson é o mais usado para encontrar raízes: a partir de um chute inicial, traça-se a reta tangente à curva (inclinação = derivada) e usa-se o ponto em que ela cruza o eixo horizontal como novo chute.
"Encontrar a raiz" significa achar o valor de x em que a função vale zero. O problema é que resolver f(x) = 0 diretamente costuma ser difícil ou impossível. A sacada do método é trocar o problema difícil por um fácil: em vez de resolver a curva, resolve-se a reta tangente a ela — e achar onde uma reta cruza o zero é conta de primeiro grau.
Como a tangente é a melhor aproximação linear da curva naquele ponto, a raiz da reta cai perto da raiz da curva. Repetindo o processo a partir dessa nova posição, a aproximação melhora a cada rodada. É a estratégia geral de boa parte dos métodos numéricos: substituir o problema real por uma versão linear local, resolver, e iterar.
Uma leitura útil para a demonstração do slide 13: quanto mais inclinada a tangente, mais curto o salto, porque uma reta íngreme cruza o eixo logo ali. Tangente quase horizontal produz salto enorme — que é exatamente o modo de falha descrito ao final desta seção.
Para calcular √a, define-se f(x) = x²−a, cuja raiz é o valor procurado. Como f'(x) = 2x, a fórmula se simplifica para x_{n+1} = ½(x_n + a/x_n) — o método clássico de raiz quadrada. Partindo de x₀ = 2 para √2:
| iteração | aproximação | erro |
|---|---|---|
| 1 | 1,500000 | 8,58 × 10⁻² |
| 2 | 1,416667 | 2,45 × 10⁻³ |
| 3 | 1,414216 | 2,12 × 10⁻⁶ |
| 5 | 1,414214 | 2,22 × 10⁻¹⁶ |
O expoente do erro aproximadamente dobra a cada iteração — convergência quadrática. Cinco passos já esgotam a precisão de um double. É por isso que o método de Newton domina a computação numérica: a tangente é a melhor aproximação linear local da função.
Modo de falha: se a derivada se anula (ou fica muito próxima de zero), a tangente fica quase horizontal, cruza o eixo muito longe do ponto atual, e a aproximação "explode" para longe da raiz — ou a divisão simplesmente estoura. É por isso que implementações reais sempre checam fabs(derivada) < tolerância antes de dividir. A demonstração do slide 13 deixa esse caso explorável: digite um número, ou use o botão "ver caso de falha" para ver a tangente quase horizontal em ação.
Um processador sabe fazer quatro coisas com números: somar, subtrair, multiplicar e dividir. Não existe um circuito que "calcule seno" — então, quando um programa chama sin(x), alguém precisou escrever esse seno usando apenas as quatro operações disponíveis. A ferramenta para isso é a série de Taylor, que troca uma função complicada por um polinômio (só somas e multiplicações) cujos coeficientes são derivadas de ordem superior avaliadas em um ponto:
A intuição por trás da fórmula: o primeiro termo diz onde a função está; o segundo, usando a primeira derivada, diz para onde ela vai; o terceiro, usando a segunda derivada, corrige o quanto ela encurva; e assim por diante. Cada derivada adicional acrescenta um detalhe mais fino do formato da curva. Por isso a aproximação é excelente perto do ponto escolhido e vai piorando conforme se afasta dele.
Para o seno em torno de zero, os primeiros termos já bastam:
Testando em x = 0,5 rad com apenas três termos, o resultado (0,479427) já acerta cinco casas decimais do valor real (0,4794255…), usando somente multiplicação e soma — tudo que o processador sabe fazer nativamente. Com cinco termos, uma implementação artesanal de poucas linhas coincide com a função sin() da biblioteca padrão até a 11ª casa decimal. Cada termo da série vem de uma derivada de ordem superior avaliada em zero — literalmente, a série de Taylor materializada em código.
O PID é o controlador mais usado na indústria, combinando três estratégias: P (proporcional) reage ao erro atual; I (integral) reage ao erro acumulado; D (derivativo) reage à velocidade com que o erro está mudando — o componente antecipatório.
Em um microcontrolador, a derivada vira diferença finita entre a leitura atual e a anterior: derivada = (erro - erro_anterior) / dt. Sem o termo D, o sistema oscila em torno do alvo; com ele, a resposta é suave — é o que estabiliza drones, mantém a temperatura de uma impressora 3D e controla braços robóticos.
Pense em alguém dirigindo até um semáforo vermelho. Um motorista que olha só a distância até o sinal mantém o pé no acelerador enquanto estiver longe — e freia tarde demais, passando da faixa. É o controlador proporcional puro: ele só reage ao erro atual.
Um motorista experiente olha também a velocidade com que o sinal se aproxima. Mesmo ainda longe, se estiver chegando rápido demais, ele já tira o pé. Essa segunda informação — a taxa de variação do erro — é exatamente o termo derivativo. O D não pergunta "quão longe estou?", e sim "quão rápido estou chegando?". É isso que transforma um controlador reativo em antecipatório.
No forno, o papel da inércia do carro é feito pela inércia térmica: a resistência elétrica continua quente mesmo depois de a potência ser cortada, e esse calor residual ainda vai passar para o bloco. Um controlador que só olhe a temperatura atual descobre tarde demais que já entregou calor além da conta.
Aqui, ao contrário do gráfico do gradiente descendente, o eixo horizontal é o tempo (em segundos) e o vertical é a temperatura do bloco (em °C). Os dois controladores partem do mesmo forno frio, com o mesmo alvo de 200 °C, e são idênticos em tudo — mesma potência máxima, mesmos ganhos P e I. A única diferença entre eles é o ganho do termo derivativo, ligado numa curva e desligado na outra.
| O que aparece | O que significa |
|---|---|
| Linha horizontal de referência | O alvo: 200 °C. É onde as duas curvas deveriam estabilizar. |
| Curva cinza | Controlador sem termo D. Sobe rápido e passa muito do alvo. |
| Curva verde | Controlador com termo D. Sobe quase tão rápido, mas "freia na curva". |
| Marcadores de pico | O ponto mais alto de cada curva — o quanto cada um ultrapassou o alvo. |
O fenômeno a apontar durante a apresentação chama-se ultrapassagem (overshoot): a distância entre o pico da curva e a linha do alvo. Ela é o custo de um controlador que reage tarde.
| controlador | pico | ultrapassagem |
|---|---|---|
| sem termo D | 236,7 °C | 36,7 °C |
| com termo D | 211,7 °C | 11,7 °C |
Redução de 3,1 vezes na ultrapassagem, sem trocar o hardware e sem deixar o aquecimento mais lento — apenas acrescentando um termo que olha a derivada do erro.
O momento mais didático do gráfico é por volta dos 10 segundos, quando as duas curvas ainda estão abaixo do alvo e visualmente parecidas. Nesse instante o controlador sem D ainda entrega 100% de potência, porque para ele o erro ainda é grande e nada mudou. O controlador com D já reduziu para 63%: o erro ainda é grande, mas está diminuindo depressa, e o termo derivativo (negativo, porque o erro encolhe) subtrai potência da conta. Ele começa a frear antes de chegar ao alvo — e é aí, num ponto em que os dois pareciam iguais, que a diferença de 25 °C no pico já está sendo decidida.
Vale explicar também por que o termo D fica negativo ao subir em direção ao alvo: o erro está diminuindo, logo (erro − erro_anterior) é negativo, e K_d multiplica esse valor negativo. Somado aos termos P e I, ele reduz a saída. É a frenagem, expressa em uma subtração.
Se a banca perguntar por que não se usa um K_d gigante para zerar a ultrapassagem: o termo derivativo amplifica ruído. Como ele é uma diferença entre duas leituras consecutivas, qualquer tremida do sensor entra na conta dividida por um dt pequeno, virando um pico enorme na saída. Na prática o sinal é filtrado antes de derivar, e K_d é mantido moderado — é o compromisso clássico entre antecipação e estabilidade, e a razão de muitos sistemas industriais rodarem apenas em PI.
Esta seção responde a uma pergunta que todo estudante de computação já fez: por que os processadores pararam de ficar mais rápidos em GHz e passaram a ganhar núcleos? A resposta está numa derivada.
Dois componentes básicos de circuito são definidos por derivadas — não é uma analogia, é a própria equação do componente. Em um capacitor, a corrente é proporcional à taxa de variação da tensão; em um indutor, a tensão é proporcional à taxa de variação da corrente:
O que essa primeira fórmula diz, em português: a corrente que um capacitor puxa não depende da tensão, e sim da pressa com que ela muda. Uma tensão alta e parada não puxa corrente nenhuma; uma tensão pequena mudando muito rápido puxa bastante.
Consequência prática: quanto mais rápido um sinal digital muda de nível, maiores são as correntes parasitas, o ruído eletromagnético e o consumo. Um transistor não é um interruptor ideal — cada trilha e cada porta carrega uma capacitância parasita que precisa ser carregada e descarregada a cada troca de 0 para 1. Subir o clock significa fazer isso mais vezes por segundo e mais depressa a cada vez:
| tempo de transição | dv/dt | corrente de pico |
|---|---|---|
| 1 ns | 1,2 × 10⁹ V/s | 12 mA |
| 100 ps (10× mais rápido) | 1,2 × 10¹⁰ V/s | 120 mA (10× mais) |
Dez vezes mais corrente pelo simples fato de comutar mais rápido — e corrente vira calor. Multiplicado por bilhões de transistores, esse é o mecanismo direto que liga frequência de clock a consumo, aquecimento e ruído. É a origem física da "parede de potência": por volta de 2005 a indústria chegou ao ponto em que subir mais o clock geraria calor impossível de dissipar, e a saída foi parar de acelerar um núcleo e passar a colocar vários lado a lado. Todo processador multinúcleo existe, em última análise, por causa dessa derivada.
Ver no slide 17O throttling em CPUs e GPUs modernas não observa só a temperatura absoluta, mas a velocidade com que ela sobe. Por extrapolação linear:
Com temperatura atual de 75 °C, limite crítico de 95 °C e taxa de 8 °C/s, o tempo até a falha é (95−75)/8 = 2,5 segundos — o firmware reduz a frequência antes de chegar aos 95 °C. O raciocínio é o mesmo de um motorista que olha o velocímetro para decidir quando frear, e não apenas a placa de "pare".
O exemplo mais eloquente compara dois cenários em que a temperatura absoluta é exatamente a mesma:
| cenário | temperatura | dT/dt | decisão do firmware |
|---|---|---|---|
| carga leve e estável | 72 °C | +2 °C/s | mantém a frequência máxima |
| carga pesada recém-iniciada | 72 °C | +12 °C/s | já reduz para 2,0 GHz |
Um controlador que olhasse só o valor absoluto trataria as duas situações de forma idêntica — e no segundo caso chegaria aos 95 °C em menos de dois segundos, forçando um desligamento de emergência. A derivada é o que transforma uma proteção reativa em preditiva, e é o mesmo princípio do termo D do PID visto acima, aplicado a outro domínio. Vale a conexão explícita na apresentação: são o mesmo conceito, resolvendo o mesmo tipo de problema — agir antes, em vez de remediar depois.
Ver no slide 17"M/M/1" é a notação padrão para o modelo mais simples de fila: chegadas aleatórias, tempos de atendimento aleatórios, um servidor. É o modelo de qualquer recurso único disputado — uma API, um banco de dados, um caixa de supermercado. Os dois parâmetros são λ (lambda), quantas requisições chegam por segundo, e μ (mu), quantas o servidor consegue atender por segundo.
A teoria das filas descreve o tempo de resposta em função da carga recebida. Até cerca de 70% da capacidade, mais carga quase não afeta o tempo de resposta; perto de 100%, a sensibilidade explode:
A fórmula de T já diz muito: o que importa não é λ nem μ isoladamente, e sim a folga entre eles (μ − λ). Um servidor de 1000 req/s recebendo 999 tem a mesma folga — e portanto o mesmo tempo de resposta — de um servidor de 10 req/s recebendo 9. Quando a folga tende a zero, T tende ao infinito: é a fila crescendo sem parar.
A derivada é a parte realmente útil para quem opera sistemas, porque ela responde "quanto custa uma requisição a mais por segundo?". Como a folga aparece ao quadrado no denominador, esse custo não cresce de forma proporcional — ele cresce de forma explosiva:
| utilização | folga (μ − λ) | tempo de resposta | custo da próxima req/s |
|---|---|---|---|
| 50% | 50 | 20 ms | +0,4 ms |
| 90% | 10 | 100 ms | +10 ms (25× mais) |
| 99% | 1 | 1000 ms | +1000 ms (2500× mais) |
O mesmo acréscimo de carga custa 2500 vezes mais a 99% de utilização do que a 50%. E note o detalhe que explica o susto das equipes de operação: entre 50% e 90% de utilização o tempo de resposta só saiu de 20 ms para 100 ms — nada dramático, os gráficos parecem saudáveis. O colapso acontece todo dentro dos últimos poucos por cento, onde ninguém está olhando.
É exatamente isso que produz o relato de que "o sistema caiu do nada". Não caiu do nada: a derivada já estava crescendo o tempo todo, e o sistema cruzou a região em que ela explode. Essa é a justificativa matemática por trás da prática de nunca dimensionar um sistema acima de 70–80% de utilização — não é conservadorismo, é reconhecer que acima disso o comportamento deixa de ser previsível. A demonstração do slide 19 deixa isso tátil: arrastando o marcador para perto de 100%, a reta tangente fica quase vertical.
Ver no slide 18 · demo no slide 19Ferramentas como Prometheus e Grafana têm funções nativas de derivada (rate, deriv) porque o valor absoluto de uma métrica costuma dizer menos que a sua velocidade de mudança. "A memória está em 60%" é pouco informativo; "está subindo 4% por minuto" indica vazamento e permite agir antes da falha.
É o contraste entre dois tipos de alerta. O alerta por limiar dispara quando a métrica cruza um valor fixo ("disco acima de 90%") — é simples, mas por definição só avisa quando o problema já está instalado, e no pior caso avisa cedo demais em sistemas que vivem estáveis em 88%. O alerta por derivada dispara pela tendência, e consegue avisar com horas de antecedência mesmo com a métrica ainda em patamar confortável.
Um disco de 500 GB com 380 GB ocupados (76%) e crescimento de 2,575 GB/h ainda esgota em ~46,5 horas — nenhum alarme por limiar fixo (tipicamente configurado em 85–90%) dispararia com apenas 76% de uso, mas a derivada já revela a urgência. É a diferença entre uma equipe agir no horário comercial e ser acordada às três da manhã. Um detalhe metodológico: estimar a derivada por regressão linear numa janela deslizante (como o Prometheus faz) é mais robusto a ruído do que a diferença ingênua entre as duas últimas leituras.
Ver no slide 20Comprar em lotes grandes reduz o custo de pedidos, mas encarece a manutenção de estoque; lotes pequenos fazem o contrário. O custo total é a soma dessas duas curvas opostas, e o lote ideal é onde a curva de custo total atinge o mínimo — ou seja, onde sua derivada se anula:
Vale explicitar o princípio, porque ele é o mais reaproveitável de todo o trabalho: no ponto mais baixo (ou mais alto) de uma curva suave, a reta tangente é horizontal — logo a derivada vale zero. Procurar o mínimo de uma função vira, então, resolver a equação f'(x) = 0. É a mesma ideia do gradiente descendente da seção de IA, com uma diferença de método: lá a função era complicada demais e o mínimo foi buscado por tentativas guiadas pela derivada; aqui a função é simples o bastante para resolver a equação de uma vez e obter uma fórmula fechada.
Com demanda de 10.000 unidades/ano, custo de pedido 50 e custo de estoque 4 por unidade/ano: Q* = √250.000 = 500 unidades. No ponto ótimo, os dois custos (pedir e estocar) se igualam — propriedade que emerge naturalmente da condição de derivada nula. Comparando três caminhos para o mesmo resultado: busca exaustiva precisa de 5000 avaliações da função de custo; a fórmula fechada (derivada resolvida uma única vez no papel) precisa de apenas 1. Em um ERP recalculando essa política para dezenas de milhares de SKUs diariamente, essa diferença deixa de ser acadêmica.
Ver no slide 20O crescimento de base de usuários costuma seguir uma curva em S (logística): lenta no início, acelerada no meio, estabilizada na maturidade. A lógica do formato é intuitiva: no começo há poucos usuários para divulgar o produto, então cresce devagar; no meio, muita gente divulgando e muito mercado disponível, então cresce rápido; no fim, quase todo mundo já usa e não sobra quem converter, então desacelera.
Duas derivadas importam aqui, e confundi-las é o erro clássico de leitura de métricas. A primeira derivada é a velocidade de aquisição — quantos usuários novos por mês. A segunda é a aceleração — se essa velocidade está aumentando ou diminuindo:
| fase da curva | total de usuários | 1ª derivada (novos/mês) | 2ª derivada |
|---|---|---|---|
| início | cresce devagar | baixa, subindo | positiva (acelerando) |
| meio (U = K/2) | cresce rápido | máxima | zero (ponto de inflexão) |
| maturidade | quase parado | baixa, caindo | negativa (desacelerando) |
A derivada dessa curva é a velocidade de aquisição de usuários:
Igualando a segunda derivada a zero, mostra-se que o crescimento máximo ocorre exatamente quando U = K/2 — metade do mercado potencial, não no final. Com K = 1.000.000 e r = 0,5/mês, o pico é de 125.000 novos usuários/mês. Esse é o número que deve dimensionar a arquitetura, não a média histórica: uma equipe que acompanhe só o total de usuários vê um gráfico sempre ascendente e conclui que tudo vai bem, mas a segunda derivada pode já ter cruzado o zero há meses, revelando que a captação está em declínio mesmo com a base total ainda crescendo.
Ver no slide 20A criptografia de curvas elípticas (ECC) protege conexões HTTPS, assinaturas digitais e carteiras de criptomoedas. Sua operação fundamental — somar dois pontos sobre a curva — é definida geometricamente por retas secantes e tangentes: traça-se a reta que passa pelos dois pontos, vê-se onde ela corta a curva pela terceira vez, e reflete-se esse ponto. Essa "soma" não tem nada a ver com somar coordenadas; é uma regra geométrica inventada para dar à curva uma estrutura algébrica utilizável.
Quando os dois pontos a somar coincidem (somar um ponto com ele mesmo, a chamada duplicação), a reta que passa por dois pontos idênticos deixa de fazer sentido — e a saída é usar a reta que toca a curva naquele ponto, ou seja, a tangente. É o caso-limite exato que a derivada resolve, e é ele que aparece milhares de vezes em cada geração de chave.
Para a curva y² = x³ + ax + b, derivando implicitamente em relação a x:
Esse coeficiente angular — uma derivada implícita, calculada em aritmética modular — entra diretamente nas fórmulas de duplicação do algoritmo. Na curva secp256k1 (a mesma do Bitcoin), gerar uma única chave pública exige 253 duplicações de ponto — 253 avaliações da derivada implícita da curva. Toda conexão HTTPS estabelecida e toda transação assinada em blockchain executa centenas dessas avaliações. Um tópico complementar, pouco explorado em trabalhos acadêmicos, mas que mostra como a derivada sustenta até a infraestrutura de confiança da internet.
A derivada não aparece na computação como um tópico isolado de cálculo, mas como infraestrutura conceitual de áreas inteiras:
| Área | O que demonstra |
|---|---|
| Inteligência Artificial | Todo treinamento é otimização guiada por gradiente |
| Visão Computacional | Reconhecer formas começa por detectar variações |
| Engenharia | O termo derivativo antecipa em vez de apenas reagir |
| Métodos Numéricos | Funções elementares vêm de métodos derivativos |
| ADS | Capacidade, custo e risco vêm de taxas de variação |
| Criptografia | A tangente sustenta o ECDSA |
"A derivada é o instrumento que permite a um sistema computacional perceber tendência, e não apenas estado."
Material de apoio complementar à apresentação "A Derivada na Computação" (IFPE). Baseado no material de pesquisa derivadas-na-computacao-pesquisa.md. Todas as saídas numéricas citadas foram obtidas por execução real dos códigos, não por estimativa.