Skip to content

Differentiation of Univariate Functions

Everything in this chapter rests on one idea: the derivative, the instantaneous rate of change of a function. It’s the slope of the tangent line, the limit of a shrinking secant, and — most importantly for us — the thing that tells gradient descent which way to step. We start in one dimension where it’s easiest to see, then generalize to gradients on the next page.

A real-life example: instantaneous speed

Your car’s odometer tells you distance; your speedometer tells you speed — the derivative of distance with respect to time. Average speed over an hour is a crude difference quotient (distance ÷ time). But your speedometer shows speed right now: the limit as the time interval shrinks to zero. That limit is the derivative.

The difference quotient

For a function y=f(x)y = f(x), the difference quotient is the slope of the secant line through two points:

δyδx=f(x+δx)f(x)δx.\frac{\delta y}{\delta x} = \frac{f(x + \delta x) - f(x)}{\delta x}.

It’s the average rate of change between xx and x+δxx + \delta x. As we shrink δx\delta x toward zero, the secant becomes the tangent, and its slope is the derivative:

dfdx:=limh0f(x+h)f(x)h.\frac{df}{dx} := \lim_{h \to 0} \frac{f(x + h) - f(x)}{h}.

The derivative points in the direction of steepest ascent of ff — the single most important sentence in this chapter.

Watch the secant become the tangent

A point rides along the curve. From it, a secant reaches to a second point hh away; as hh shrinks (the readout ticks down), the secant swings into the tangent line, and its slope settles on the derivative f(x)f'(x):

sketch Secant → tangent: the derivative p5.js
A secant line through two points on the curve, separated by h. As h shrinks toward 0, the secant becomes the tangent, and its slope becomes the derivative f'(x). The moving point sweeps along the curve.

As h0h \to 0 the secant slope closes in on the tangent slope — the definition of the derivative, made visible.

The rules you’ll actually use

Rather than take limits every time, we use rules. With f=dfdxf' = \frac{df}{dx}:

Power:(xn)=nxn1Sum:(f+g)=f+gProduct:(fg)=fg+fgQuotient:(fg)=fgfgg2Chain:(g(f(x)))=g(f(x))f(x)\begin{aligned} \text{Power:} &\quad (x^n)' = n\,x^{n-1}\\ \text{Sum:} &\quad (f + g)' = f' + g'\\ \text{Product:} &\quad (fg)' = f'g + fg'\\ \text{Quotient:} &\quad \left(\tfrac{f}{g}\right)' = \frac{f'g - fg'}{g^2}\\ \text{Chain:} &\quad \big(g(f(x))\big)' = g'(f(x))\,f'(x) \end{aligned}

The chain rule is the star: it differentiates compositions, and composition is exactly how neural networks are built (layer after layer). Backpropagation is the chain rule applied at scale.

Taylor series: functions as polynomials

Any smooth function can be approximated near a point x0x_0 by a Taylor polynomial built from its derivatives:

Tn(x)=k=0nf(k)(x0)k!(xx0)k.T_n(x) = \sum_{k=0}^{n} \frac{f^{(k)}(x_0)}{k!}(x - x_0)^k.

As nn \to \infty (for analytic functions) this becomes the Taylor series, an exact representation. It’s how calculators compute sin\sin, exp\exp, and log\log, and how we build local approximations of loss functions in optimization.

diagram Diagram mermaid

NumPy: numeric and symbolic derivatives

derivatives.py
import numpy as np
 
# f(x) = x^3 ; f'(x) = 3x^2. Numeric derivative via the difference quotient.
def f(x): return x**3
def numeric_derivative(f, x, h=1e-6):
    return (f(x + h) - f(x)) / h
 
x0 = 2.0
print("numeric f'(2) :", round(numeric_derivative(f, x0), 4))   # ~12
print("exact   f'(2) :", 3 * x0**2)                              # 12
 
# Chain rule check: h(x) = (2x+1)^4 -> h'(x) = 8(2x+1)^3
def h(x): return (2*x + 1)**4
print("numeric h'(1) :", round(numeric_derivative(h, 1.0), 2))   # ~216
print("exact   h'(1) :", 8 * (2*1 + 1)**3)                       # 216
derivatives.py
import numpy as np
 
# f(x) = x^3 ; f'(x) = 3x^2. Numeric derivative via the difference quotient.
def f(x): return x**3
def numeric_derivative(f, x, h=1e-6):
    return (f(x + h) - f(x)) / h
 
x0 = 2.0
print("numeric f'(2) :", round(numeric_derivative(f, x0), 4))   # ~12
print("exact   f'(2) :", 3 * x0**2)                              # 12
 
# Chain rule check: h(x) = (2x+1)^4 -> h'(x) = 8(2x+1)^3
def h(x): return (2*x + 1)**4
print("numeric h'(1) :", round(numeric_derivative(h, 1.0), 2))   # ~216
print("exact   h'(1) :", 8 * (2*1 + 1)**3)                       # 216
text
numeric f'(2) : 12.0
exact   f'(2) : 12.0
numeric h'(1) : 216.0
exact   h'(1) : 216
text
numeric f'(2) : 12.0
exact   f'(2) : 12.0
numeric h'(1) : 216.0
exact   h'(1) : 216

Why this matters for ML

  • Gradient descent steps against the derivative/gradient to minimize loss — the derivative literally tells the model which way to move.
  • The chain rule is backpropagation’s engine: it differentiates the deeply-composed function a neural network computes.
  • Taylor approximations underlie optimization theory (why gradient/Newton steps work) and the Laplace approximation in Bayesian ML.

🧪 Try It Yourself

Exercise 1 – Numeric derivative

Exercise 2 – Chain rule

Exercise 3 – Taylor approximation of eˣ

Recap

  • The derivative is the limit of the difference quotient — the slope of the tangent, the direction of steepest ascent.
  • Use the power, sum, product, quotient, and chain rules instead of taking limits by hand.
  • The chain rule differentiates compositions — the seed of backpropagation.
  • Taylor series approximate any smooth function with polynomials built from its derivatives.

Next: derivatives of functions with many inputs — the gradient.

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did